diff --git a/catalog-model/pom.xml b/catalog-model/pom.xml
index 08697a2..63f8d12 100644
--- a/catalog-model/pom.xml
+++ b/catalog-model/pom.xml
@@ -1,5 +1,5 @@
 <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">
+		 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>
 
@@ -20,7 +20,7 @@
 			<version>${project.version}</version>
 			<scope>provided</scope>
 		</dependency>
-		
+
 		<dependency>
 			<groupId>org.openecomp.sdc.be</groupId>
 			<artifactId>common-be</artifactId>
@@ -31,14 +31,14 @@
 		<dependency>
 			<groupId>ch.qos.logback</groupId>
 			<artifactId>logback-classic</artifactId>
-            <version>${logback.version}</version>
+			<version>${logback.version}</version>
 			<scope>provided</scope>
 		</dependency>
 
 		<dependency>
 			<groupId>ch.qos.logback</groupId>
 			<artifactId>logback-core</artifactId>
-            <version>${logback.version}</version>
+			<version>${logback.version}</version>
 			<scope>provided</scope>
 		</dependency>
 
@@ -119,7 +119,7 @@
 
 		<dependency>
 			<groupId>org.onap.sdc.sdc-titan-cassandra</groupId>
-  			<artifactId>sdc-titan-cassandra</artifactId>
+			<artifactId>sdc-titan-cassandra</artifactId>
 			<version>${sdc.titan.version}</version>
 			<scope>provided</scope>
 			<exclusions>
@@ -142,14 +142,14 @@
 		<dependency>
 			<groupId>org.apache.httpcomponents</groupId>
 			<artifactId>httpclient</artifactId>
-            <version>${httpclient.version}</version>
+			<version>${httpclient.version}</version>
 			<scope>provided</scope>
 		</dependency>
 
 		<dependency>
 			<groupId>org.apache.httpcomponents</groupId>
 			<artifactId>httpcore</artifactId>
-            <version>${httpcore.version}</version>
+			<version>${httpcore.version}</version>
 			<scope>provided</scope>
 		</dependency>
 
@@ -234,19 +234,19 @@
 			<version>${commons-jci-core.version}</version>
 			<scope>test</scope>
 		</dependency>
-        <dependency>
-            <groupId>org.powermock</groupId>
-            <artifactId>powermock-module-junit4</artifactId>
-            <version>1.7.0RC4</version>
-            <scope>test</scope>
-        </dependency>
+		<dependency>
+			<groupId>org.powermock</groupId>
+			<artifactId>powermock-module-junit4</artifactId>
+			<version>1.7.0RC4</version>
+			<scope>test</scope>
+		</dependency>
 		<dependency>
 			<groupId>org.powermock</groupId>
 			<artifactId>powermock-api-mockito-common</artifactId>
 			<version>1.6.5</version>
 			<scope>test</scope>
 		</dependency>
-    </dependencies>
+	</dependencies>
 	<build>
 		<plugins>
 			<plugin>
@@ -259,4 +259,4 @@
 			</plugin>
 		</plugins>
 	</build>
-</project>
+</project>
\ No newline at end of file
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/config/CatalogModelSpringConfig.java b/catalog-model/src/main/java/org/openecomp/sdc/be/config/CatalogModelSpringConfig.java
index 1dcbfbf..9e0b104 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/config/CatalogModelSpringConfig.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/config/CatalogModelSpringConfig.java
@@ -1,13 +1,21 @@
 package org.openecomp.sdc.be.config;
 
+import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 
 @Configuration
 @ComponentScan({"org.openecomp.sdc.be.model.operations.impl",
                 "org.openecomp.sdc.be.model.cache",
-                "org.openecomp.sdc.be.model.jsontitan.operations"
-
+                "org.openecomp.sdc.be.model.jsontitan.utils",
+                "org.openecomp.sdc.be.model.jsontitan.operations",
 })
 public class CatalogModelSpringConfig {
+
+    @Bean
+    public DataTypeValidatorConverter dataTypeValidatorConverter() {
+        return DataTypeValidatorConverter.getInstance();
+    }
+
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.java
index b155e50..f97b998 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.java
@@ -20,59 +20,52 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterInfo;
 
-public class AdditionalInformationDefinition extends AdditionalInfoParameterDataDefinition implements Serializable {
+import java.util.List;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 5266684455492488001L;
+public class AdditionalInformationDefinition extends AdditionalInfoParameterDataDefinition {
 
-	private String parentUniqueId;
+    private String parentUniqueId;
+
+    public AdditionalInformationDefinition() {
+        super();
+    }
+
+    public AdditionalInformationDefinition(AdditionalInfoParameterDataDefinition p, String parentUniqueId,
+            List<AdditionalInfoParameterInfo> parameters) {
+        super(p);
+        this.parentUniqueId = parentUniqueId;
+        setParameters(parameters);
+    }
+    public AdditionalInformationDefinition(AdditionalInfoParameterDataDefinition p){
+        this.setUniqueId(p.getUniqueId());
+        this.setCreationTime(p.getCreationTime());
+        this.setModificationTime(p.getModificationTime());
+        setParameters(p.getParameters());
+    }
+    public AdditionalInformationDefinition(AdditionalInformationDefinition pd) {
+        this.setUniqueId(pd.getUniqueId());
+        this.setCreationTime(pd.getCreationTime());
+        this.setModificationTime(pd.getModificationTime());
+        this.parentUniqueId = pd.parentUniqueId;
+    }
+
+    public String getParentUniqueId() {
+        return parentUniqueId;
+    }
+
+    public void setParentUniqueId(String parentUniqueId) {
+        this.parentUniqueId = parentUniqueId;
+    }
 
 
-	public AdditionalInformationDefinition() {
-		super();
-	}
 
-	public AdditionalInformationDefinition(AdditionalInfoParameterDataDefinition p, String parentUniqueId,
-			List<AdditionalInfoParameterInfo> parameters) {
-		super(p);
-		this.parentUniqueId = parentUniqueId;
-		setParameters(parameters);
-	}
-	public AdditionalInformationDefinition(AdditionalInfoParameterDataDefinition p){
-		this.setUniqueId(p.getUniqueId());
-		this.setCreationTime(p.getCreationTime());
-		this.setModificationTime(p.getModificationTime());
-		setParameters(p.getParameters());
-	}
-	public AdditionalInformationDefinition(AdditionalInformationDefinition pd) {
-		this.setUniqueId(pd.getUniqueId());
-		this.setCreationTime(pd.getCreationTime());
-		this.setModificationTime(pd.getModificationTime());
-		this.parentUniqueId = pd.parentUniqueId;
-	}
-
-	public String getParentUniqueId() {
-		return parentUniqueId;
-	}
-
-	public void setParentUniqueId(String parentUniqueId) {
-		this.parentUniqueId = parentUniqueId;
-	}
-
-	
-
-	@Override
-	public String toString() {
-		return "AdditionalInformationDefinition [ parentUniqueId=" + parentUniqueId + " "
-				+ super.toString() + "]";
-	}
+    @Override
+    public String toString() {
+        return "AdditionalInformationDefinition [ parentUniqueId=" + parentUniqueId + " "
+                + super.toString() + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AnnotationTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AnnotationTypeDefinition.java
new file mode 100644
index 0000000..8cddfbd
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AnnotationTypeDefinition.java
@@ -0,0 +1,42 @@
+package org.openecomp.sdc.be.model;
+
+import org.openecomp.sdc.be.datatypes.elements.AnnotationTypeDataDefinition;
+import org.openecomp.sdc.be.model.utils.TypeCompareUtils;
+
+import java.util.List;
+import java.util.Objects;
+
+public class AnnotationTypeDefinition extends AnnotationTypeDataDefinition {
+
+
+    public AnnotationTypeDefinition() {
+        super();
+    }
+
+    public AnnotationTypeDefinition(AnnotationTypeDataDefinition annotationTypeDataDefinition) {
+        super(annotationTypeDataDefinition);
+    }
+
+    protected List<PropertyDefinition> properties;
+
+    public List<PropertyDefinition> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<PropertyDefinition> properties) {
+        this.properties = properties;
+    }
+
+    /**
+     * This method compares definition properties and ignores products such as
+     * actual graph ids that were already assigned
+     */
+    public boolean isSameDefinition(AnnotationTypeDefinition other) {
+        if (this == other) return true;
+        if (other == null) return false;
+
+        return Objects.equals(type, other.type) &&
+               Objects.equals(description, other.description) &&
+               TypeCompareUtils.propertiesEquals(properties, other.properties);
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java
index 434422e..bdffc8a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java
@@ -7,9 +7,9 @@
  * 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.
@@ -20,116 +20,112 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
+import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.HeatParameterDataDefinition;
+
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.HeatParameterDataDefinition;
+public class ArtifactDefinition extends ArtifactDataDefinition {
 
-public class ArtifactDefinition extends ArtifactDataDefinition implements Serializable {
+    /**
+     * Base64 encoded Artifact file data
+     */
+    private byte[] payloadData;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -8323923665449071631L;
+    public ArtifactDefinition() {
+    }
 
-	/**
-	 * Base64 encoded Artifact file data
-	 */
-	private byte[] payloadData;
+    public ArtifactDefinition(Map<String, Object> art) {
+        super(art);
+    }
+
+    public ArtifactDefinition(ArtifactDataDefinition a) {
+        super(a);
+    }
+
+    public ArtifactDefinition(ArtifactDefinition a) {
+        super(a);
+        this.payloadData = a.payloadData;
+    }
+
+    public ArtifactDefinition(ArtifactDataDefinition a, String payloadData) {
+        super(a);
+        setPayloadData(payloadData);
+    }
+
+    public byte[] getPayloadData() {
+        return payloadData;
+    }
+
+    public void setPayload(byte[] payloadData) {
+        this.payloadData = payloadData;
+    }
+
+    public void setPayloadData(String payloadData) {
+        if (payloadData != null) {
+            this.payloadData = payloadData.getBytes();
+        }
+    }
+
+    public List<HeatParameterDefinition> getListHeatParameters() {
+        List<HeatParameterDefinition> res = null;
+        List<HeatParameterDataDefinition> heatParameters = super.getHeatParameters();
+        if (heatParameters != null) {
+            res = heatParameters.stream().map(HeatParameterDefinition::new).collect(Collectors.toList());
+        }
+        return res;
+    }
+
+    public void setListHeatParameters(List<HeatParameterDefinition> properties) {
+        List<HeatParameterDataDefinition> res = null;
+
+        if (properties != null) {
+            res = properties.stream().map(HeatParameterDataDefinition::new).collect(Collectors.toList());
+        }
+        super.setHeatParameters(res);
+    }
 
 
-	public byte[] getPayloadData() {
-		return payloadData;
-	}
+    public boolean checkEsIdExist() {
+        if ((getEsId() != null) && (!getEsId().trim().isEmpty())) {
+            return true;
+        }
+        return false;
+    }
 
-	public void setPayload(byte[] payloadData) {
-		this.payloadData = payloadData;
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
 
-	public void setPayloadData(String payloadData) {
-		if (payloadData != null) {
-			this.payloadData = payloadData.getBytes();
-		}
-	}
+        result = prime * result + Arrays.hashCode(payloadData);
+        return result;
+    }
 
-	public ArtifactDefinition() {
-		super();
-	}
-	public ArtifactDefinition(Map<String, Object> art) {
-		super(art);
-	}
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ArtifactDefinition other = (ArtifactDefinition) obj;
 
-	public ArtifactDefinition(ArtifactDataDefinition a) {
-		super(a);
-
-	}
-	
-	public ArtifactDefinition(ArtifactDefinition a) {
-		super(a);
-		this.payloadData = a.payloadData;
-		
-	}
-
-	public ArtifactDefinition(ArtifactDataDefinition a, String payloadData) {
-		super(a);
-		setPayloadData(payloadData);
-	}
-
-	public List<HeatParameterDefinition> getListHeatParameters() {
-		List<HeatParameterDefinition> res = null;
-		List<HeatParameterDataDefinition> heatParameters = super.getHeatParameters();
-		if(heatParameters != null){
-			res = heatParameters.stream().map(hp -> new HeatParameterDefinition(hp)).collect(Collectors.toList());
-		}
-		return res;
-	}
-
-	public void setListHeatParameters(List<HeatParameterDefinition> properties) {
-		List<HeatParameterDataDefinition> res = null;
-		
-		if(properties != null){
-			res = properties.stream().map(hp -> new HeatParameterDataDefinition(hp)).collect(Collectors.toList());
-		}
-		super.setHeatParameters(res);
-	}
-
-
-
-	public boolean checkEsIdExist() {
-		if ((getEsId() != null) && (!getEsId().trim().isEmpty())) {
-			return true;
-		}
-		return false;
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-	
-		result = prime * result + ((payloadData == null) ? 0 : payloadData.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		ArtifactDefinition other = (ArtifactDefinition) obj;
-	
-	
-		if (payloadData == null) {
-			if (other.payloadData != null)
-				return false;
-		} else if (!payloadData.equals(other.payloadData))
-			return false;
-		return true;
-	}
+        if (payloadData == null) {
+            if (other.payloadData != null) {
+                return false;
+            }
+        }
+        else if (!Arrays.equals(payloadData, other.payloadData)) {
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.java
index a761d74..ec55209 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.java
@@ -22,43 +22,43 @@
 
 public class ArtifactType {
 
-	private String name;
+    private String name;
 
-	public String getName() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((name == null) ? 0 : name.hashCode());
-		return result;
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        return result;
+    }
 
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj) {
-			return true;
-		}
-		if (obj == null) {
-			return false;
-		}
-		if (getClass() != obj.getClass()) {
-			return false;
-		}
-		ArtifactType other = (ArtifactType) obj;
-		if (name == null) {
-			if (other.getClass() != null) {
-				return false;
-			}
-		} else if (!name.equals(other.getName())) {
-			return false;
-		}
-		return true;
-	}
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ArtifactType other = (ArtifactType) obj;
+        if (name == null) {
+            if (other.getClass() != null) {
+                return false;
+            }
+        } else if (!name.equals(other.getName())) {
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.java
index 7172ddc..4fa0536 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.java
@@ -22,24 +22,24 @@
 
 public class ArtifactUiDownloadData {
 
-	// POJO for UI artifact download, holding artifact filename and base64
-	// content
-	String artifactName;
-	String base64Contents;
+    // POJO for UI artifact download, holding artifact filename and base64
+    // content
+    String artifactName;
+    String base64Contents;
 
-	public void setArtifactName(String artifactName) {
-		this.artifactName = artifactName;
-	}
+    public void setArtifactName(String artifactName) {
+        this.artifactName = artifactName;
+    }
 
-	public void setBase64Contents(String base64Contents) {
-		this.base64Contents = base64Contents;
-	}
+    public void setBase64Contents(String base64Contents) {
+        this.base64Contents = base64Contents;
+    }
 
-	public String getArtifactName() {
-		return artifactName;
-	}
+    public String getArtifactName() {
+        return artifactName;
+    }
 
-	public String getBase64Contents() {
-		return base64Contents;
-	}
+    public String getBase64Contents() {
+        return base64Contents;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.java
index 2f9cf48..bee09fb 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.java
@@ -24,33 +24,33 @@
 import java.util.Map;
 
 public class CapReqDef {
-	Map<String, List<CapabilityDefinition>> capabilities;
-	Map<String, List<RequirementDefinition>> requirements;
+    Map<String, List<CapabilityDefinition>> capabilities;
+    Map<String, List<RequirementDefinition>> requirements;
 
-	public CapReqDef() {
-		super();
-	}
+    public CapReqDef() {
+        super();
+    }
 
-	public CapReqDef(Map<String, List<RequirementDefinition>> requirements,
-			Map<String, List<CapabilityDefinition>> capabilities) {
-		super();
-		this.capabilities = capabilities;
-		this.requirements = requirements;
-	}
+    public CapReqDef(Map<String, List<RequirementDefinition>> requirements,
+            Map<String, List<CapabilityDefinition>> capabilities) {
+        super();
+        this.capabilities = capabilities;
+        this.requirements = requirements;
+    }
 
-	public Map<String, List<CapabilityDefinition>> getCapabilities() {
-		return capabilities;
-	}
+    public Map<String, List<CapabilityDefinition>> getCapabilities() {
+        return capabilities;
+    }
 
-	public Map<String, List<RequirementDefinition>> getRequirements() {
-		return requirements;
-	}
+    public Map<String, List<RequirementDefinition>> getRequirements() {
+        return requirements;
+    }
 
-	public void setCapabilities(Map<String, List<CapabilityDefinition>> capabilities) {
-		this.capabilities = capabilities;
-	}
+    public void setCapabilities(Map<String, List<CapabilityDefinition>> capabilities) {
+        this.capabilities = capabilities;
+    }
 
-	public void setRequirements(Map<String, List<RequirementDefinition>> requirements) {
-		this.requirements = requirements;
-	}
+    public void setRequirements(Map<String, List<RequirementDefinition>> requirements) {
+        this.requirements = requirements;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java
index ccc5248..a74243e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java
@@ -20,92 +20,120 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
+import com.google.common.collect.Lists;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.collections.SetUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 /**
  * Specifies the capabilities that the Node Type exposes.
  */
-public class CapabilityDefinition extends CapabilityDataDefinition implements Serializable {
+public class CapabilityDefinition extends CapabilityDataDefinition {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -3871825415338268030L;
-
-	
-	/**
-	 * The properties field contains all properties defined for
-	 * CapabilityDefinition
-	 */
-	private List<ComponentInstanceProperty> properties;
-
-	// specifies the resource instance holding this requirement
+    /**
+     * The properties field contains all properties defined for
+     * CapabilityDefinition
+     */
+    private List<ComponentInstanceProperty> properties;
 
 
-	public CapabilityDefinition() {
-		super();
-	}
-	
-	public CapabilityDefinition(CapabilityDataDefinition cap) {
-		super(cap);
-	}
+    public CapabilityDefinition() {
+        super();
+    }
 
-	public CapabilityDefinition(CapabilityDefinition other) {
-		super((CapabilityDefinition)other);
-	
-		if (other.properties != null) {
-			this.properties = new ArrayList<>(other.properties.stream().map(p -> new ComponentInstanceProperty(p)).collect(Collectors.toList()));
+    public CapabilityDefinition(CapabilityDataDefinition cap) {
+        super(cap);
+    }
+
+	public CapabilityDefinition(CapabilityTypeDefinition other, String ownerName, String name, CapabilityDataDefinition.OwnerType ownerType) {
+		super(other);
+        this.setOwnerName(ownerName);
+        this.setOwnerType(ownerType);
+        this.setName(name);
+        this.setParentName(name);
+		if (MapUtils.isNotEmpty(other.getProperties())) {
+			this.properties = Lists.newArrayList(other.getProperties().values().stream().map(ComponentInstanceProperty::new).collect(Collectors.toList()));
 		}
-		
 	}
 
+    public CapabilityDefinition(CapabilityDefinition other) {
+        super((CapabilityDefinition)other);
 
+        if (other.properties != null) {
+			this.properties = new ArrayList<>(other.properties.stream().map(ComponentInstanceProperty::new).collect(Collectors.toList()));
+        }
+    }
 
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + ((properties == null) ? 0 : properties.hashCode());
-		return result;
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + ((properties == null) ? 0 : properties.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        CapabilityDefinition other = (CapabilityDefinition) obj;
+        if (properties == null) {
+            if (other.properties != null)
+                return false;
+        } else if (!SetUtils.isEqualSet(properties, other.getProperties()))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "CapabilityDefinition [properties=" + properties + "]";
+    }
+
+    public List<ComponentInstanceProperty> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<ComponentInstanceProperty> properties) {
+        this.properties = properties;
+    }
+
+	public void updateCapabilityProperties(CapabilityDefinition capabilityDefinition) {
+		if(CollectionUtils.isNotEmpty(getProperties()) && capabilityDefinition!= null && CollectionUtils.isNotEmpty(capabilityDefinition.getProperties())){
+			Map<String, ComponentInstanceProperty> propertiesInfo = capabilityDefinition.getProperties()
+					.stream()
+					.collect(Collectors.toMap(ComponentInstanceProperty::getName, p->p));
+			getProperties().forEach(p->p.updateCapabilityProperty(propertiesInfo.get(p.getName())));
+		}
 	}
 
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		CapabilityDefinition other = (CapabilityDefinition) obj;
-		if (properties == null) {
-			if (other.properties != null)
-				return false;
-		} else if (!properties.equals(other.properties))
-			return false;
-		return true;
-	}
+    public void updateEmptyCapabilityOwnerFields(String ownerId, String ownerName, OwnerType ownerType) {
+        if (StringUtils.isEmpty(getOwnerId())){
+            setOwnerId(ownerId);
+            if(getPath() == null){
+                setPath(new ArrayList<>());
+            }
+            if(!getPath().contains(ownerId)){
+                getPath().add(ownerId);
+            }
+            setOwnerName(ownerName);
+            setOwnerTypeIfEmpty(ownerType);
+        }
+    }
 
-	@Override
-	public String toString() {
-		return "CapabilityDefinition [properties=" + properties + "]";
-	}
-
-	public List<ComponentInstanceProperty> getProperties() {
-		return properties;
-	}
-
-	public void setProperties(List<ComponentInstanceProperty> properties) {
-		this.properties = properties;
-	}
-
-
-
-
-
+    private void setOwnerTypeIfEmpty(OwnerType ownerType) {
+        if(getOwnerType() == null){
+            setOwnerType(ownerType);
+        }
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityRequirementRelationship.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityRequirementRelationship.java
index 54b998d..f9a1092 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityRequirementRelationship.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityRequirementRelationship.java
@@ -1,39 +1,32 @@
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-
 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
 /**
  * Contains the Capability, Requirement and Relationship info
  */
-public class CapabilityRequirementRelationship implements Serializable {
-	
-	private static final long serialVersionUID = 1L;
-	
-	private RelationshipInfo relation;
-	private CapabilityDataDefinition capability;
-	private RequirementDataDefinition requirement;
-	
-	public RelationshipInfo getRelation() {
-		return relation;
-	}
-	public void setRelation(RelationshipInfo relation) {
-		this.relation = relation;
-	}
-	public CapabilityDataDefinition getCapability() {
-		return capability;
-	}
-	public void setCapability(CapabilityDataDefinition capability) {
-		this.capability = capability;
-	}
-	public RequirementDataDefinition getRequirement() {
-		return requirement;
-	}
-	public void setRequirement(RequirementDataDefinition requirement) {
-		this.requirement = requirement;
-	}
-	public static long getSerialversionuid() {
-		return serialVersionUID;
-	}
+public class CapabilityRequirementRelationship {
+
+    private RelationshipInfo relation;
+    private CapabilityDataDefinition capability;
+    private RequirementDataDefinition requirement;
+
+    public RelationshipInfo getRelation() {
+        return relation;
+    }
+    public void setRelation(RelationshipInfo relation) {
+        this.relation = relation;
+    }
+    public CapabilityDataDefinition getCapability() {
+        return capability;
+    }
+    public void setCapability(CapabilityDataDefinition capability) {
+        this.capability = capability;
+    }
+    public RequirementDataDefinition getRequirement() {
+        return requirement;
+    }
+    public void setRequirement(RequirementDataDefinition requirement) {
+        this.requirement = requirement;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java
index 4291ee7..016c117 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java
@@ -20,46 +20,63 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.datatypes.elements.CapabilityTypeDataDefinition;
+import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
+
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * Specifies the capabilities that the Node Type exposes.
  */
+@SuppressWarnings("serial")
 public class CapabilityTypeDefinition extends CapabilityTypeDataDefinition {
 
-	private String derivedFrom;
+    private String derivedFrom;
 
-	private Map<String, PropertyDefinition> properties;
+    private Map<String, PropertyDefinition> properties;
 
-	public String getDerivedFrom() {
-		return derivedFrom;
+    public String getDerivedFrom() {
+        return derivedFrom;
+    }
+
+    public void setDerivedFrom(String derivedFrom) {
+        this.derivedFrom = derivedFrom;
+    }
+
+    public Map<String, PropertyDefinition> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Map<String, PropertyDefinition> properties) {
+        this.properties = properties;
+    }
+
+    public CapabilityTypeDefinition() {
+        super();
+    }
+
+    public CapabilityTypeDefinition(CapabilityTypeDataDefinition p) {
+        super(p);
+    }
+	
+	public CapabilityTypeDefinition(CapabilityDefinition cp) {
+		this.setUniqueId(cp.getUniqueId());
+		this.setDescription ( cp.getDescription());
+		this.setType(cp.getType());
+		this.setValidSourceTypes( cp.getValidSourceTypes()); 
+		this.setProperties(cp.getProperties().stream().collect(Collectors.toMap(ComponentInstanceProperty::getName, PropertyDefinition::new)));
 	}
 
-	public void setDerivedFrom(String derivedFrom) {
-		this.derivedFrom = derivedFrom;
+	public CapabilityTypeDefinition(CapabilityTypeData ctd) {
+		this.setUniqueId(ctd.getUniqueId());
+		this.setType(ctd.getCapabilityTypeDataDefinition().getType());
+		this.setDescription ( ctd.getCapabilityTypeDataDefinition().getDescription());
+		this.setValidSourceTypes( ctd.getCapabilityTypeDataDefinition().getValidSourceTypes()); 
 	}
 
-	public Map<String, PropertyDefinition> getProperties() {
-		return properties;
-	}
-
-	public void setProperties(Map<String, PropertyDefinition> properties) {
-		this.properties = properties;
-	}
-
-	public CapabilityTypeDefinition() {
-		super();
-	}
-
-	public CapabilityTypeDefinition(CapabilityTypeDataDefinition p) {
-		super(p);
-	}
-
-	@Override
-	public String toString() {
-		return super.toString() + " [ derivedFrom=" + derivedFrom + ", properties=" + properties + " ]";
-	}
-
+    @Override
+    public String toString() {
+        return super.toString() + " [ derivedFrom=" + derivedFrom + ", properties=" + properties + " ]";
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.java
index 5e5edf9..c10521d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.java
@@ -24,29 +24,29 @@
 
 public class CapabiltyInstance {
 
-	private String uniqueId;
+    private String uniqueId;
 
-	private Map<String, String> properties;
+    private Map<String, String> properties;
 
-	public String getUniqueId() {
-		return uniqueId;
-	}
+    public String getUniqueId() {
+        return uniqueId;
+    }
 
-	public void setUniqueId(String uniqueId) {
-		this.uniqueId = uniqueId;
-	}
+    public void setUniqueId(String uniqueId) {
+        this.uniqueId = uniqueId;
+    }
 
-	public Map<String, String> getProperties() {
-		return properties;
-	}
+    public Map<String, String> getProperties() {
+        return properties;
+    }
 
-	public void setProperties(Map<String, String> properties) {
-		this.properties = properties;
-	}
+    public void setProperties(Map<String, String> properties) {
+        this.properties = properties;
+    }
 
-	@Override
-	public String toString() {
-		return "CapabiltyInstance [uniqueId=" + uniqueId + ", properties=" + properties + "]";
-	}
+    @Override
+    public String toString() {
+        return "CapabiltyInstance [uniqueId=" + uniqueId + ", properties=" + properties + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.java
index 03cab66..33d69ac 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.java
@@ -22,44 +22,44 @@
 
 public class Category {
 
-	private String name;// will be changed to categoryDisplayName
+    private String name;// will be changed to categoryDisplayName
 
-	public String getName() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((name == null) ? 0 : name.hashCode());
-		return result;
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        return result;
+    }
 
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		Category other = (Category) obj;
-		if (name == null) {
-			if (other.name != null)
-				return false;
-		} else if (!name.equals(other.name))
-			return false;
-		return true;
-	}
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        Category other = (Category) obj;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        return true;
+    }
 
-	@Override
-	public String toString() {
-		return "Category [name=" + name + "]";
-	}
+    @Override
+    public String toString() {
+        return "Category [name=" + name + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java
index c17c3fc..579dcdb 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java
@@ -7,9 +7,9 @@
  * 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.
@@ -21,6 +21,8 @@
 package org.openecomp.sdc.be.model;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.collect.Maps;
+import org.apache.commons.collections.MapUtils;
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.utils.MapUtil;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
@@ -28,750 +30,891 @@
 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
+import static java.util.Collections.emptyList;
+import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import java.util.*;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyMap;
+import static java.util.stream.Collectors.toMap;
+import static org.apache.commons.collections.CollectionUtils.isEmpty;
+import static org.apache.commons.collections.MapUtils.isEmpty;
 
-public abstract class Component implements Serializable {
+public abstract class Component {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -6373756459967949120L;
+    private ComponentMetadataDefinition componentMetadataDefinition;
+    private Map<String, ArtifactDefinition> artifacts;
+    private Map<String, ArtifactDefinition> deploymentArtifacts;
+    private Map<String, ArtifactDefinition> toscaArtifacts;
+    private List<CategoryDefinition> categories;
+    private List<ComponentInstance> componentInstances;
+    private List<RequirementCapabilityRelDef> componentInstancesRelations;
+    private Map<String, List<ComponentInstanceInput>> componentInstancesInputs;
+    private Map<String, List<ComponentInstanceProperty>> componentInstancesProperties;
+    private Map<String, List<ComponentInstanceProperty>> componentInstancesAttributes;
+    private Map<String, List<CapabilityDefinition>> capabilities;
+    private Map<String, List<RequirementDefinition>> requirements;
+    private List<InputDefinition> inputs;
+    private List<GroupDefinition> groups;
+    private Map<String, PolicyDefinition> policies;
+    private String derivedFromGenericType;
+    private String derivedFromGenericVersion;
+    private String toscaType;
+    protected List<AdditionalInformationDefinition> additionalInformation;
 
-	private ComponentMetadataDefinition componentMetadataDefinition;
-	private Map<String, ArtifactDefinition> artifacts;
-	private Map<String, ArtifactDefinition> deploymentArtifacts;
-	private Map<String, ArtifactDefinition> toscaArtifacts;
-	private List<CategoryDefinition> categories;
-	private List<ComponentInstance> componentInstances;
-	private List<RequirementCapabilityRelDef> componentInstancesRelations;
-	private Map<String, List<ComponentInstanceInput>> componentInstancesInputs;
-	private Map<String, List<ComponentInstanceProperty>> componentInstancesProperties;
-	private Map<String, List<ComponentInstanceProperty>> componentInstancesAttributes;
-	private Map<String, List<CapabilityDefinition>> capabilities;
-	private Map<String, List<RequirementDefinition>> requirements;
-	private List<InputDefinition> inputs;
-	private List<GroupDefinition> groups;
-	private Map<String, PolicyDefinition> policies;
-	private String derivedFromGenericType;
-	private String derivedFromGenericVersion;
-	private String toscaType;
-	protected List<AdditionalInformationDefinition> additionalInformation;
-	
-	public String getDerivedFromGenericVersion() {
-		return derivedFromGenericVersion;
-	}
+    public Component(ComponentMetadataDefinition componentMetadataDefinition) {
+        this.componentMetadataDefinition = componentMetadataDefinition;
+    }
 
-	public void setDerivedFromGenericVersion(String derivedFromGenericVersion) {
-		this.derivedFromGenericVersion = derivedFromGenericVersion;
-	}
+    public String getDerivedFromGenericVersion() {
+        return derivedFromGenericVersion;
+    }
 
-	public String getDerivedFromGenericType() {
-		return derivedFromGenericType;
-	}
+    public void setDerivedFromGenericVersion(String derivedFromGenericVersion) {
+        this.derivedFromGenericVersion = derivedFromGenericVersion;
+    }
 
-	public void setDerivedFromGenericType(String derivedFromGenericType) {
-		this.derivedFromGenericType = derivedFromGenericType;
-	}
-	
-	public Component(ComponentMetadataDefinition componentMetadataDefinition) {
-		this.componentMetadataDefinition = componentMetadataDefinition;
-	}
+    public String getDerivedFromGenericType() {
+        return derivedFromGenericType;
+    }
 
-	@JsonIgnore
-	public ComponentMetadataDefinition getComponentMetadataDefinition() {
-		return componentMetadataDefinition;
-	}
+    public void setDerivedFromGenericType(String derivedFromGenericType) {
+        this.derivedFromGenericType = derivedFromGenericType;
+    }
 
-	public Map<String, ArtifactDefinition> getArtifacts() {
-		return artifacts;
-	}
 
-	public void setArtifacts(Map<String, ArtifactDefinition> artifacts) {
-		this.artifacts = artifacts;
-	}
+    @JsonIgnore
+    public ComponentMetadataDefinition getComponentMetadataDefinition() {
+        return componentMetadataDefinition;
+    }
 
-	public Map<String, ArtifactDefinition> getToscaArtifacts() {
-		return toscaArtifacts;
-	}
+    public Map<String, ArtifactDefinition> getArtifacts() {
+        return artifacts;
+    }
 
-	public void setToscaArtifacts(Map<String, ArtifactDefinition> toscaArtifacts) {
-		this.toscaArtifacts = toscaArtifacts;
-	}
+    public void setArtifacts(Map<String, ArtifactDefinition> artifacts) {
+        this.artifacts = artifacts;
+    }
 
-	public String getUniqueId() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getUniqueId();
-	}
+    public Map<String, ArtifactDefinition> getToscaArtifacts() {
+        return toscaArtifacts;
+    }
 
-	public void setUniqueId(String uniqueId) {
-		componentMetadataDefinition.getMetadataDataDefinition().setUniqueId(uniqueId);
-	}
+    public void setToscaArtifacts(Map<String, ArtifactDefinition> toscaArtifacts) {
+        this.toscaArtifacts = toscaArtifacts;
+    }
 
-	public void setName(String name) {
-		componentMetadataDefinition.getMetadataDataDefinition().setName(name);
-	}
+    public String getUniqueId() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getUniqueId();
+    }
 
-	public void setVersion(String version) {
-		componentMetadataDefinition.getMetadataDataDefinition().setVersion(version);
-	}
+    public void setUniqueId(String uniqueId) {
+        componentMetadataDefinition.getMetadataDataDefinition().setUniqueId(uniqueId);
+    }
 
-	public void setHighestVersion(Boolean isHighestVersion) {
-		componentMetadataDefinition.getMetadataDataDefinition().setHighestVersion(isHighestVersion);
-	}
+    public void setName(String name) {
+        componentMetadataDefinition.getMetadataDataDefinition().setName(name);
+    }
 
-	public void setCreationDate(Long creationDate) {
-		componentMetadataDefinition.getMetadataDataDefinition().setCreationDate(creationDate);
-	}
+    public void setVersion(String version) {
+        componentMetadataDefinition.getMetadataDataDefinition().setVersion(version);
+    }
 
-	public void setLastUpdateDate(Long lastUpdateDate) {
-		componentMetadataDefinition.getMetadataDataDefinition().setLastUpdateDate(lastUpdateDate);
-	}
+    public void setHighestVersion(Boolean isHighestVersion) {
+        componentMetadataDefinition.getMetadataDataDefinition().setHighestVersion(isHighestVersion);
+    }
 
-	public void setDescription(String description) {
-		componentMetadataDefinition.getMetadataDataDefinition().setDescription(description);
-	}
+    public void setCreationDate(Long creationDate) {
+        componentMetadataDefinition.getMetadataDataDefinition().setCreationDate(creationDate);
+    }
 
-	public void setState(LifecycleStateEnum state) {
-		componentMetadataDefinition.getMetadataDataDefinition().setState(state.name());
-	}
+    public void setLastUpdateDate(Long lastUpdateDate) {
+        componentMetadataDefinition.getMetadataDataDefinition().setLastUpdateDate(lastUpdateDate);
+    }
 
-	public void setTags(List<String> tags) {
-		componentMetadataDefinition.getMetadataDataDefinition().setTags(tags);
-	}
+    public void setDescription(String description) {
+        componentMetadataDefinition.getMetadataDataDefinition().setDescription(description);
+    }
 
-	public void setConformanceLevel(String conformanceLevel) {
-		componentMetadataDefinition.getMetadataDataDefinition().setConformanceLevel(conformanceLevel);
-	}
-	
-	public void setIcon(String icon) {
-		componentMetadataDefinition.getMetadataDataDefinition().setIcon(icon);
-	}
+    public void setState(LifecycleStateEnum state) {
+        componentMetadataDefinition.getMetadataDataDefinition().setState(state.name());
+    }
 
-	public void setContactId(String contactId) {
-		componentMetadataDefinition.getMetadataDataDefinition().setContactId(contactId);
-	}
+    public void setTags(List<String> tags) {
+        componentMetadataDefinition.getMetadataDataDefinition().setTags(tags);
+    }
 
-	public String getCreatorUserId() {
-		return this.componentMetadataDefinition.getMetadataDataDefinition().getCreatorUserId();
-	}
+    public void setConformanceLevel(String conformanceLevel) {
+        componentMetadataDefinition.getMetadataDataDefinition().setConformanceLevel(conformanceLevel);
+    }
 
-	public void setCreatorUserId(String creatorUserId) {
-		this.componentMetadataDefinition.getMetadataDataDefinition().setCreatorUserId(creatorUserId);
-	}
+    public void setIcon(String icon) {
+        componentMetadataDefinition.getMetadataDataDefinition().setIcon(icon);
+    }
 
-	public String getCreatorFullName() {
-		return this.componentMetadataDefinition.getMetadataDataDefinition().getCreatorFullName();
-	}
+    public void setContactId(String contactId) {
+        componentMetadataDefinition.getMetadataDataDefinition().setContactId(contactId);
+    }
 
-	public void setCreatorFullName(String creatorFullName) {
-		this.componentMetadataDefinition.getMetadataDataDefinition().setCreatorFullName(creatorFullName);
-	}
+    public String getCreatorUserId() {
+        return this.componentMetadataDefinition.getMetadataDataDefinition().getCreatorUserId();
+    }
 
-	public String getLastUpdaterUserId() {
-		return this.componentMetadataDefinition.getMetadataDataDefinition().getLastUpdaterUserId();
-	}
+    public void setCreatorUserId(String creatorUserId) {
+        this.componentMetadataDefinition.getMetadataDataDefinition().setCreatorUserId(creatorUserId);
+    }
 
-	public void setLastUpdaterUserId(String lastUpdaterUserId) {
-		this.componentMetadataDefinition.getMetadataDataDefinition().setLastUpdaterUserId(lastUpdaterUserId);
-	}
+    public String getCreatorFullName() {
+        return this.componentMetadataDefinition.getMetadataDataDefinition().getCreatorFullName();
+    }
 
-	public String getLastUpdaterFullName() {
-		return this.componentMetadataDefinition.getMetadataDataDefinition().getLastUpdaterFullName();
-	}
+    public void setCreatorFullName(String creatorFullName) {
+        this.componentMetadataDefinition.getMetadataDataDefinition().setCreatorFullName(creatorFullName);
+    }
 
-	public void setLastUpdaterFullName(String lastUpdaterFullName) {
-		this.componentMetadataDefinition.getMetadataDataDefinition().setLastUpdaterFullName(lastUpdaterFullName);
-	}
+    public String getLastUpdaterUserId() {
+        return this.componentMetadataDefinition.getMetadataDataDefinition().getLastUpdaterUserId();
+    }
 
-	public String getName() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getName();
-	}
+    public void setLastUpdaterUserId(String lastUpdaterUserId) {
+        this.componentMetadataDefinition.getMetadataDataDefinition().setLastUpdaterUserId(lastUpdaterUserId);
+    }
 
-	public String getVersion() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getVersion();
-	}
+    public String getLastUpdaterFullName() {
+        return this.componentMetadataDefinition.getMetadataDataDefinition().getLastUpdaterFullName();
+    }
 
-	public Boolean isHighestVersion() {
-		return componentMetadataDefinition.getMetadataDataDefinition().isHighestVersion();
-	}
+    public void setLastUpdaterFullName(String lastUpdaterFullName) {
+        this.componentMetadataDefinition.getMetadataDataDefinition().setLastUpdaterFullName(lastUpdaterFullName);
+    }
 
-	public Long getCreationDate() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getCreationDate();
-	}
+    public String getName() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getName();
+    }
 
-	public Long getLastUpdateDate() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getLastUpdateDate();
-	}
+    public String getVersion() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getVersion();
+    }
 
-	public String getDescription() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getDescription();
-	}
+    public Boolean isHighestVersion() {
+        return componentMetadataDefinition.getMetadataDataDefinition().isHighestVersion();
+    }
 
-	public LifecycleStateEnum getLifecycleState() {
-		if (componentMetadataDefinition.getMetadataDataDefinition().getState() != null) {
-			return LifecycleStateEnum.valueOf(componentMetadataDefinition.getMetadataDataDefinition().getState());
-		} else {
-			return null;
-		}
-	}
+    public Long getCreationDate() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getCreationDate();
+    }
 
-	public List<String> getTags() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getTags();
-	}
+    public Long getLastUpdateDate() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getLastUpdateDate();
+    }
 
-	public String getConformanceLevel() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getConformanceLevel();
-	}
-	
-	public String getIcon() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getIcon();
-	}
+    public String getDescription() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getDescription();
+    }
 
-	public String getContactId() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getContactId();
-	}
+    public LifecycleStateEnum getLifecycleState() {
+        if (componentMetadataDefinition.getMetadataDataDefinition().getState() != null) {
+            return LifecycleStateEnum.valueOf(componentMetadataDefinition.getMetadataDataDefinition().getState());
+        }
+        else {
+            return null;
+        }
+    }
 
-	public List<InputDefinition> getInputs() {
-		return inputs;
-	}
+    public List<String> getTags() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getTags();
+    }
 
-	public void setInputs(List<InputDefinition> inputs) {
-		this.inputs = inputs;
-	}
+    public String getConformanceLevel() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getConformanceLevel();
+    }
 
-	public void setLifecycleState(LifecycleStateEnum state) {
-		if (state != null) {
-			this.componentMetadataDefinition.getMetadataDataDefinition().setState(state.name());
-		}
-	}
+    public String getIcon() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getIcon();
+    }
 
-	public String getUUID() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getUUID();
-	}
+    public String getContactId() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getContactId();
+    }
 
-	public void setUUID(String uUID) {
-		componentMetadataDefinition.getMetadataDataDefinition().setUUID(uUID);
-	}
+    public List<InputDefinition> getInputs() {
+        return inputs;
+    }
 
-	public void setSystemName(String systemName) {
-		componentMetadataDefinition.getMetadataDataDefinition().setSystemName(systemName);
-	}
+    public List<InputDefinition> safeGetInputs() {
+        return inputs == null ? new ArrayList<>() : inputs;
+    }
 
-	public String getSystemName() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getSystemName();
-	}
+    public void setInputs(List<InputDefinition> inputs) {
+        this.inputs = inputs;
+    }
 
-	public void setAllVersions(Map<String, String> allVersions) {
-		componentMetadataDefinition.getMetadataDataDefinition().setAllVersions(allVersions);
-	}
+    public void setLifecycleState(LifecycleStateEnum state) {
+        if (state != null) {
+            this.componentMetadataDefinition.getMetadataDataDefinition().setState(state.name());
+        }
+    }
 
-	public Map<String, String> getAllVersions() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getAllVersions();
-	}
+    public String getUUID() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getUUID();
+    }
 
-	public Map<String, ArtifactDefinition> getDeploymentArtifacts() {
-		return deploymentArtifacts;
-	}
+    public void setUUID(String uUID) {
+        componentMetadataDefinition.getMetadataDataDefinition().setUUID(uUID);
+    }
 
-	public void setDeploymentArtifacts(Map<String, ArtifactDefinition> deploymentArtifacts) {
-		this.deploymentArtifacts = deploymentArtifacts;
-	}
+    public void setSystemName(String systemName) {
+        componentMetadataDefinition.getMetadataDataDefinition().setSystemName(systemName);
+    }
 
-	public Map<String, ArtifactDefinition> getAllArtifacts() {
-		HashMap<String, ArtifactDefinition> allArtifacts = new HashMap<>();
-		allArtifacts.putAll(Optional.ofNullable(this.deploymentArtifacts).orElse(Collections.emptyMap()));
-		allArtifacts.putAll(Optional.ofNullable(this.artifacts).orElse(Collections.emptyMap()));
-		return allArtifacts;
-	}
+    public String getSystemName() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getSystemName();
+    }
 
-	public List<CategoryDefinition> getCategories() {
-		return categories;
-	}
+    public void setAllVersions(Map<String, String> allVersions) {
+        componentMetadataDefinition.getMetadataDataDefinition().setAllVersions(allVersions);
+    }
 
-	public void setCategories(List<CategoryDefinition> categories) {
-		this.categories = categories;
-	}
+    public Map<String, String> getAllVersions() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getAllVersions();
+    }
 
-	public String getNormalizedName() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getNormalizedName();
-	}
+    public Map<String, ArtifactDefinition> getDeploymentArtifacts() {
+        return deploymentArtifacts;
+    }
 
-	public void setNormalizedName(String normalizedName) {
-		componentMetadataDefinition.getMetadataDataDefinition().setNormalizedName(normalizedName);
-	}
+    public void setDeploymentArtifacts(Map<String, ArtifactDefinition> deploymentArtifacts) {
+        this.deploymentArtifacts = deploymentArtifacts;
+    }
 
-	public ComponentTypeEnum getComponentType() {
-		return this.componentMetadataDefinition.getMetadataDataDefinition().getComponentType();
-	}
+    public Map<String, ArtifactDefinition> getAllArtifacts() {
+        HashMap<String, ArtifactDefinition> allArtifacts = new HashMap<>();
+        allArtifacts.putAll(Optional.ofNullable(this.deploymentArtifacts).orElse(emptyMap()));
+        allArtifacts.putAll(Optional.ofNullable(this.artifacts).orElse(emptyMap()));
+        return allArtifacts;
+    }
 
-	public void setComponentType(ComponentTypeEnum componentType) {
-		this.componentMetadataDefinition.getMetadataDataDefinition().setComponentType(componentType);
-	}
+    public List<CategoryDefinition> getCategories() {
+        return categories;
+    }
 
-	public Map<String, List<CapabilityDefinition>> getCapabilities() {
-		return capabilities;
-	}
+    public void setCategories(List<CategoryDefinition> categories) {
+        this.categories = categories;
+    }
 
-	public void setCapabilities(Map<String, List<CapabilityDefinition>> capabilities) {
-		this.capabilities = capabilities;
-	}
+    public String getNormalizedName() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getNormalizedName();
+    }
 
-	public Map<String, List<RequirementDefinition>> getRequirements() {
-		return requirements;
-	}
+    public void setNormalizedName(String normalizedName) {
+        componentMetadataDefinition.getMetadataDataDefinition().setNormalizedName(normalizedName);
+    }
 
-	public void setRequirements(Map<String, List<RequirementDefinition>> requirements) {
-		this.requirements = requirements;
-	}
+    public ComponentTypeEnum getComponentType() {
+        return this.componentMetadataDefinition.getMetadataDataDefinition().getComponentType();
+    }
 
-	public List<ComponentInstance> getComponentInstances() {
-		return componentInstances;
-	}
+    public void setComponentType(ComponentTypeEnum componentType) {
+        this.componentMetadataDefinition.getMetadataDataDefinition().setComponentType(componentType);
+    }
 
-	public Optional<ComponentInstance> fetchInstanceById(String instanceId) {
-		return Optional.ofNullable(MapUtil.toMap(componentInstances, ComponentInstance::getUniqueId).get(instanceId));
-	}
-
-	@SuppressWarnings("unchecked")
-	public Map<String, ArtifactDefinition> safeGetComponentInstanceDeploymentArtifacts(String componentInstanceId) {
-		Optional<ComponentInstance> componentInstanceById = getComponentInstanceById(componentInstanceId);
-		Map<String, ArtifactDefinition> instanceDeploymentArtifacts = componentInstanceById.get().safeGetDeploymentArtifacts();
-		return instanceDeploymentArtifacts != null ? instanceDeploymentArtifacts : Collections.emptyMap();
-	}
-
-	@SuppressWarnings("unchecked")
-	public Map<String, ArtifactDefinition> safeGetComponentInstanceInformationalArtifacts(String componentInstanceId) {
-		Optional<ComponentInstance> componentInstanceById = getComponentInstanceById(componentInstanceId);
-		Map<String, ArtifactDefinition> instanceInformationalArtifacts = componentInstanceById.get().safeGetInformationalArtifacts();
-		return instanceInformationalArtifacts != null ? instanceInformationalArtifacts : Collections.emptyMap();
-	}
-
-	public List<ArtifactDefinition> safeGetComponentInstanceHeatArtifacts(String componentInstanceId) {
-		Optional<ComponentInstance> componentInstanceById = getComponentInstanceById(componentInstanceId);
-		List<ArtifactDefinition> instanceHeatEnvArtifacts = Optional.ofNullable(componentInstanceById.get().safeGetDeploymentArtifacts().values()).orElse(new ArrayList<ArtifactDefinition>())
-				.stream()
-				.filter(artifact -> artifact.getArtifactType() != null && artifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.name()))
-				.collect(Collectors.toList());
-		return instanceHeatEnvArtifacts == null ? emptyList() : instanceHeatEnvArtifacts;
-	}
-
-	public void setComponentInstances(List<ComponentInstance> resourceInstances) {
-		this.componentInstances = resourceInstances;
-	}
-
-	public List<RequirementCapabilityRelDef> getComponentInstancesRelations() {
-		return componentInstancesRelations;
-	}
-
-	public void setComponentInstancesRelations(List<RequirementCapabilityRelDef> resourceInstancesRelations) {
-		this.componentInstancesRelations = resourceInstancesRelations;
-	}
-
-	public Map<String, List<ComponentInstanceProperty>> getComponentInstancesProperties() {
-		return componentInstancesProperties;
-	}
-
-	public List<ComponentInstanceProperty> safeGetComponentInstanceProperties(String cmptInstacneId) {
-		return this.safeGetComponentInstanceEntity(cmptInstacneId, this.componentInstancesProperties);
-	}
-
-	public List<ComponentInstanceInput> safeGetComponentInstanceInput(String comptInstanceId) {
-		return this.safeGetComponentInstanceEntity(comptInstanceId, this.componentInstancesInputs);
-	}
-
-	public void setComponentInstancesProperties(
-			Map<String, List<ComponentInstanceProperty>> resourceInstancesProperties) {
-		this.componentInstancesProperties = resourceInstancesProperties;
-	}
-
-	public Boolean getIsDeleted() {
-		return componentMetadataDefinition.getMetadataDataDefinition().isDeleted();
-	}
-
-	public void setIsDeleted(Boolean isDeleted) {
-		componentMetadataDefinition.getMetadataDataDefinition().setIsDeleted(isDeleted);
-	}
-
-	public String getProjectCode() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getProjectCode();
-	}
-
-	public void setProjectCode(String projectCode) {
-		componentMetadataDefinition.getMetadataDataDefinition().setProjectCode(projectCode);
-	}
-
-	public String getCsarUUID() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getCsarUUID();
-	}
-
-	public void setCsarUUID(String csarUUID) {
-		componentMetadataDefinition.getMetadataDataDefinition().setCsarUUID(csarUUID);
-	}
-
-	public String getCsarVersion() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getCsarVersion();
-	}
-
-	public void setCsarVersion(String csarVersion) {
-		componentMetadataDefinition.getMetadataDataDefinition().setCsarVersion(csarVersion);
-	}
-
-	public String getImportedToscaChecksum() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getImportedToscaChecksum();
-	}
-
-	public void setImportedToscaChecksum(String importedToscaChecksum) {
-		componentMetadataDefinition.getMetadataDataDefinition().setImportedToscaChecksum(importedToscaChecksum);
-	}
-
-	public String getInvariantUUID() {
-		return componentMetadataDefinition.getMetadataDataDefinition().getInvariantUUID();
-	}
-
-	public void setInvariantUUID(String invariantUUID) {
-		componentMetadataDefinition.getMetadataDataDefinition().setInvariantUUID(invariantUUID);
-	}
-
-	public Optional<ComponentInstance> getComponentInstanceById(String id) {
-		if (componentInstances == null) {
-			return Optional.empty();
-		}
-		return componentInstances.stream().filter(instance -> id.equals(instance.getUniqueId())).findFirst();
-	}
-
-	public List<GroupDefinition> getGroups() {
-		return groups;
-	}
-	public Optional<GroupDefinition> getGroupById(String id){
-		return groups.stream().filter(g -> g.getUniqueId().equals(id)).findAny();
-
-	}
-
-	public void setGroups(List<GroupDefinition> groups) {
-		this.groups = groups;
-	}
-	
-	public Map<String, PolicyDefinition> getPolicies() {
-		return policies;
-	}
-
-	public void setPolicies(Map<String, PolicyDefinition> policies) {
-		this.policies = policies;
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((artifacts == null) ? 0 : artifacts.hashCode());
-		result = prime * result + ((categories == null) ? 0 : categories.hashCode());
-		result = prime * result + ((componentMetadataDefinition == null) ? 0 : componentMetadataDefinition.hashCode());
-		result = prime * result + ((deploymentArtifacts == null) ? 0 : deploymentArtifacts.hashCode());
-		result = prime * result + ((capabilities == null) ? 0 : capabilities.hashCode());
-		result = prime * result + ((requirements == null) ? 0 : requirements.hashCode());
-		result = prime * result + ((componentInstances == null) ? 0 : componentInstances.hashCode());
-		result = prime * result
-				+ ((componentInstancesProperties == null) ? 0 : componentInstancesProperties.hashCode());
-		result = prime * result
-				+ ((componentInstancesAttributes == null) ? 0 : componentInstancesAttributes.hashCode());
-		result = prime * result + ((componentInstancesInputs == null) ? 0 : componentInstancesInputs.hashCode());
-		result = prime * result + ((componentInstancesRelations == null) ? 0 : componentInstancesRelations.hashCode());
-		result = prime * result + ((groups == null) ? 0 : groups.hashCode());
-		result = prime * result + ((policies == null) ? 0 : policies.hashCode());
-		result = prime * result + ((derivedFromGenericType == null) ? 0 : derivedFromGenericType.hashCode());
-		result = prime * result + ((derivedFromGenericVersion == null) ? 0 : derivedFromGenericVersion.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		Component other = (Component) obj;
-		if (artifacts == null) {
-			if (other.artifacts != null)
-				return false;
-		} else if (!artifacts.equals(other.artifacts))
-			return false;
-		if (categories == null) {
-			if (other.categories != null)
-				return false;
-		} else if (!categories.equals(other.categories))
-			return false;
-		if (componentMetadataDefinition == null) {
-			if (other.componentMetadataDefinition != null)
-				return false;
-		} else if (!componentMetadataDefinition.equals(other.componentMetadataDefinition))
-			return false;
-		if (deploymentArtifacts == null) {
-			if (other.deploymentArtifacts != null)
-				return false;
-		} else if (!deploymentArtifacts.equals(other.deploymentArtifacts))
-			return false;
-		if (componentInstances == null) {
-			if (other.componentInstances != null)
-				return false;
-		} else if (!componentInstances.equals(other.componentInstances))
-			return false;
-		if (componentInstancesProperties == null) {
-			if (other.componentInstancesProperties != null)
-				return false;
-		} else if (!componentInstancesProperties.equals(other.componentInstancesProperties))
-			return false;
-
-		if (!Objects.equals(componentInstancesAttributes, other.componentInstancesAttributes)) {
-			return false;
-		}
-		if (!Objects.equals(componentInstancesInputs, other.componentInstancesInputs)) {
-			return false;
-		}
-		if (componentInstancesRelations == null) {
-			if (other.componentInstancesRelations != null)
-				return false;
-		} else if (!componentInstancesRelations.equals(other.componentInstancesRelations))
-			return false;
-		if (requirements == null) {
-			if (other.requirements != null)
-				return false;
-		} else if (!requirements.equals(other.requirements))
-			return false;
-		if (capabilities == null) {
-			if (other.capabilities != null)
-				return false;
-		} else if (!capabilities.equals(other.capabilities))
-			return false;
-		if (groups == null) {
-			if (other.groups != null)
-				return false;
-		} else if (!groups.equals(other.groups))
-			return false;
-		if (policies == null) {
-			if (other.policies != null)
-				return false;
-		} else if (!policies.equals(other.policies))
-			return false;
-		if (derivedFromGenericType == null) {
-			if (other.derivedFromGenericType != null)
-				return false;
-		} else if (!derivedFromGenericType.equals(other.derivedFromGenericType))
-			return false;
-		if (derivedFromGenericVersion == null) {
-			if (other.derivedFromGenericVersion != null)
-				return false;
-		} else if (!derivedFromGenericVersion.equals(other.derivedFromGenericVersion))
-			return false;
-		return true;
-	}
-
-	public void addCategory(String category, String subCategory) {
-		if (category != null || subCategory != null) {
-			if (categories == null) {
-				categories = new ArrayList<>();
-			}
-			CategoryDefinition selectedCategory = null;
-			for (CategoryDefinition categoryDef : categories) {
-				if (categoryDef.getName().equals(category)) {
-					selectedCategory = categoryDef;
-				}
-			}
-			if (selectedCategory == null) {
-				selectedCategory = new CategoryDefinition();
-				selectedCategory.setName(category);
-				categories.add(selectedCategory);
-			}
-			List<SubCategoryDefinition> subcategories = selectedCategory.getSubcategories();
-			if (subcategories == null) {
-				subcategories = new ArrayList<>();
-				selectedCategory.setSubcategories(subcategories);
-			}
-			SubCategoryDefinition selectedSubcategory = null;
-			for (SubCategoryDefinition subcategory : subcategories) {
-				if (subcategory.getName().equals(subCategory)) {
-					selectedSubcategory = subcategory;
-				}
-			}
-			if (selectedSubcategory == null) {
-				selectedSubcategory = new SubCategoryDefinition();
-				selectedSubcategory.setName(subCategory);
-				subcategories.add(selectedSubcategory);
-			}
-		}
-	}
-
-	public void addCategory(CategoryDefinition category) {
-		addCategory(category, null);
-	}
-
-	public void addCategory(CategoryDefinition category, SubCategoryDefinition subCategory) {
-		if (categories == null) {
-			categories = new ArrayList<>();
-		}
-		boolean foundCat = false;
-		for (CategoryDefinition cat : categories) {
-			if (cat.getName().equals(category.getName())) {
-				foundCat = true;
-				if (subCategory != null) {
-					List<SubCategoryDefinition> subcategories = cat.getSubcategories();
-					if (subcategories == null) {
-						subcategories = new ArrayList<>();
-						cat.setSubcategories(subcategories);
-					}
-					for (SubCategoryDefinition subcat : subcategories) {
-						boolean foundSub = false;
-						if (subcat.getName().equals(subCategory.getName())) {
-							foundSub = true;
-						}
-						if (foundSub == false) {
-							subcategories.add(subCategory);
-							break;
-						}
-					}
-				}
-			}
-		}
-		if (foundCat == false) {
-			if (subCategory != null) {
-				category.addSubCategory(subCategory);
-			}
-			categories.add(category);
-		}
-	}
-
-	public Map<String, List<ComponentInstanceProperty>> getComponentInstancesAttributes() {
-		return componentInstancesAttributes;
-	}
-
-	public void setComponentInstancesAttributes(
-			Map<String, List<ComponentInstanceProperty>> componentInstancesAttributes) {
-		this.componentInstancesAttributes = componentInstancesAttributes;
-	}
-
-	public Map<String, List<ComponentInstanceInput>> getComponentInstancesInputs() {
-		return componentInstancesInputs;
-	}
-
-	public List<ComponentInstanceInput> safeGetComponentInstanceInputsByName(String cmptInstanceName) {
-		List<ComponentInstanceInput> emptyPropsList = emptyList();
-		if (this.componentInstancesInputs == null) {
-			return emptyPropsList;
-		}
-		Optional<List<ComponentInstanceInput>> instanceInputsByName = this.componentInstances.stream()
-				.filter(ci -> ci.getName().equals(cmptInstanceName))
-				.map(ComponentInstance::getUniqueId)
-				.map(instanceId -> safeGetComponentInstanceEntity(instanceId, this.componentInstancesInputs))
-				.findAny();
-		return instanceInputsByName.orElse(emptyPropsList);
-	}
-
-	private <T> List<T> safeGetComponentInstanceEntity(String cmptInstanceId, Map<String, List<T>> instanceEntities) {
-		List<T> emptyPropsList = emptyList();
-		if (instanceEntities == null) {
-			return emptyPropsList;
-		}
-		List<T> cmptInstanceProps = instanceEntities.get(cmptInstanceId);
-		return cmptInstanceProps == null ? emptyPropsList : cmptInstanceProps;
-	}
-
-
-
-	public void setComponentInstancesInputs(Map<String, List<ComponentInstanceInput>> componentInstancesInputs) {
-		this.componentInstancesInputs = componentInstancesInputs;
-	}
-
-	public void setSpecificComponetTypeArtifacts(Map<String, ArtifactDefinition> specificComponentTypeArtifacts) {
-		// Implement where needed
-	}
-	
-	public void setMetadataDefinition(ComponentMetadataDefinition metadataDefinition) {
-		this.componentMetadataDefinition = metadataDefinition;
-	}
-	
-	public String fetchGenericTypeToscaNameFromConfig(){
-		// Implement where needed
-		return ConfigurationManager.getConfigurationManager().getConfiguration().getGenericAssetNodeTypes().get(this.assetType());
-	}
-	
-	public String assetType(){
-		// Implement where needed
-		return this.getComponentType().getValue();
-	}
-	
-	public boolean shouldGenerateInputs(){
-		// Implement where needed
-		return true;
-	}
-	
-	public boolean deriveFromGeneric(){
-		// Implement where needed
-		return true;
-	}
-	
-	public void setDerivedFromGenericInfo(Resource genericType){
-		derivedFromGenericType = genericType.getToscaResourceName();
-		derivedFromGenericVersion = genericType.getVersion();
-	}
+    public Map<String, List<CapabilityDefinition>> getCapabilities() {
+        if (MapUtils.isEmpty(capabilities)) {
+            capabilities = Maps.newHashMap();
+        }
+        return capabilities;
+    }
 
-	public boolean isTopologyTemplate() {
-		return ToscaElementTypeEnum.TopologyTemplate.getValue().equals(toscaType);
-	}
+    public void setCapabilities(Map<String, List<CapabilityDefinition>> capabilities) {
+        this.capabilities = capabilities;
+    }
 
-	public String getToscaType() {
-		return toscaType;
-	}
+    public Map<String, List<RequirementDefinition>> getRequirements() {
+        return requirements;
+    }
 
-	public void setToscaType(String toscaType) {
-		this.toscaType = toscaType;
-	}
+    public void setRequirements(Map<String, List<RequirementDefinition>> requirements) {
+        this.requirements = requirements;
+    }
 
-	public List<AdditionalInformationDefinition> getAdditionalInformation() {
-		return additionalInformation;
-	}
+    public List<ComponentInstance> getComponentInstances() {
+        return componentInstances;
+    }
+    
+    public List<ComponentInstance> safeGetComponentInstances() {
+    	if(componentInstances != null) {
+    		return componentInstances;
+    	}else {
+    		return emptyList();
+    	}
+    }
 
-	public void setAdditionalInformation(List<AdditionalInformationDefinition> additionalInformation) {
-		this.additionalInformation = additionalInformation;
-	}
+    public Optional<ComponentInstance> fetchInstanceById(String instanceId) {
+        return Optional.ofNullable(MapUtil.toMap(componentInstances, ComponentInstance::getUniqueId).get(instanceId));
+    }
 
-	public PolicyDefinition getPolicyById(String id) {
-		return policies != null ? policies.get(id) : null;
-	}
+    public Map<String, ArtifactDefinition> safeGetComponentInstanceDeploymentArtifacts(String componentInstanceId) {
+        return getComponentInstanceById(componentInstanceId).map(ComponentInstance::safeGetDeploymentArtifacts)
+                                                            .orElse(emptyMap());
+    }
 
-	public List<PolicyDefinition> resolvePoliciesList() {
-		if (policies == null) {
-			return emptyList();
-		}
-		return new ArrayList<>(policies.values());
-	}
+    public Map<String, ArtifactDefinition> safeGetComponentInstanceInformationalArtifacts(String componentInstanceId) {
+        return getComponentInstanceById(componentInstanceId).map(ComponentInstance::safeGetInformationalArtifacts)
+                                                            .orElse(emptyMap());
+    }
 
-	public List<PolicyDefinition> resolvePoliciesByComponentInstanceTarget(String instanceId) {
-		if (policies == null) {
-			return emptyList();
-		}
-		return policies.values().stream()
-				.filter(policy -> policy.containsCmptInstanceAsTarget(instanceId))
+    public List<ArtifactDefinition> safeGetComponentInstanceHeatArtifacts(String componentInstanceId) {
+        return safeGetComponentInstanceDeploymentArtifacts(componentInstanceId)
+                .values()
+                .stream()
+                .filter(artifact -> ArtifactTypeEnum.HEAT_ENV.name().equals(artifact.getArtifactType()))
                 .collect(Collectors.toList());
-	}
+    }
 
-	public List<GroupDefinition> resolveGroupsByMember(String instanceId) {
-		if (groups == null) {
-			return emptyList();
-		}
-		return groups.stream()
-				     .filter(group -> group.containsInstanceAsMember(instanceId))
-				     .collect(Collectors.toList());
-	}
+    public void setComponentInstances(List<ComponentInstance> resourceInstances) {
+        this.componentInstances = resourceInstances;
+    }
+
+    public List<RequirementCapabilityRelDef> getComponentInstancesRelations() {
+        return componentInstancesRelations;
+    }
+
+    public void setComponentInstancesRelations(List<RequirementCapabilityRelDef> resourceInstancesRelations) {
+        this.componentInstancesRelations = resourceInstancesRelations;
+    }
+
+    public Map<String, List<ComponentInstanceProperty>> getComponentInstancesProperties() {
+        return componentInstancesProperties;
+    }
+
+    public Map<String, List<ComponentInstanceProperty>> safeGetComponentInstancesProperties() {
+        return componentInstancesProperties == null ? emptyMap() : componentInstancesProperties;
+    }
+
+    public Map<String, List<ComponentInstanceInput>> safeGetComponentInstancesInputs() {
+        return componentInstancesInputs == null ? emptyMap() : componentInstancesInputs;
+    }
+
+    public List<ComponentInstanceProperty> safeGetComponentInstanceProperties(String cmptInstacneId) {
+        return this.safeGetComponentInstanceEntity(cmptInstacneId, this.componentInstancesProperties);
+    }
+
+    public List<ComponentInstanceInput> safeGetComponentInstanceInput(String comptInstanceId) {
+        return this.safeGetComponentInstanceEntity(comptInstanceId, this.componentInstancesInputs);
+    }
+
+    public void setComponentInstancesProperties(
+            Map<String, List<ComponentInstanceProperty>> resourceInstancesProperties) {
+        this.componentInstancesProperties = resourceInstancesProperties;
+    }
+
+    public Boolean getIsDeleted() {
+        return componentMetadataDefinition.getMetadataDataDefinition().isDeleted();
+    }
+
+    public void setIsDeleted(Boolean isDeleted) {
+        componentMetadataDefinition.getMetadataDataDefinition().setIsDeleted(isDeleted);
+    }
+
+    public String getProjectCode() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getProjectCode();
+    }
+
+    public void setProjectCode(String projectCode) {
+        componentMetadataDefinition.getMetadataDataDefinition().setProjectCode(projectCode);
+    }
+
+    public String getCsarUUID() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getCsarUUID();
+    }
+
+    public void setCsarUUID(String csarUUID) {
+        componentMetadataDefinition.getMetadataDataDefinition().setCsarUUID(csarUUID);
+    }
+
+    public String getCsarVersion() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getCsarVersion();
+    }
+
+    public void setCsarVersion(String csarVersion) {
+        componentMetadataDefinition.getMetadataDataDefinition().setCsarVersion(csarVersion);
+    }
+
+    public String getImportedToscaChecksum() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getImportedToscaChecksum();
+    }
+
+    public void setImportedToscaChecksum(String importedToscaChecksum) {
+        componentMetadataDefinition.getMetadataDataDefinition().setImportedToscaChecksum(importedToscaChecksum);
+    }
+
+    public String getInvariantUUID() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getInvariantUUID();
+    }
+
+    public void setInvariantUUID(String invariantUUID) {
+        componentMetadataDefinition.getMetadataDataDefinition().setInvariantUUID(invariantUUID);
+    }
+
+    public Optional<ComponentInstance> getComponentInstanceById(String id) {
+        return getComponentInstanceByPredicate(instance -> id.equals(instance.getUniqueId()));
+    }
+
+    public Optional<ComponentInstance> getComponentInstanceByName(String name) {
+        return getComponentInstanceByPredicate(instance -> name.equals(instance.getName()));
+    }
+
+    private Optional<ComponentInstance> getComponentInstanceByPredicate(Predicate<ComponentInstance> predicate) {
+        if (componentInstances == null) {
+            return Optional.empty();
+        }
+        return componentInstances.stream().filter(predicate).findFirst();
+    }
+
+    public List<GroupDefinition> getGroups() {
+        return groups;
+    }
+
+    public List<GroupDefinition> safeGetGroups() {
+        return groups == null ? emptyList() : groups;
+    }
+
+    public Optional<GroupDefinition> getGroupById(String id) {
+        return getGroupByPredicate(group -> group.getUniqueId().equals(id));
+    }
+
+    public Optional<GroupDefinition> getGroupByInvariantName(String name) {
+        return getGroupByPredicate(group -> name.equals(group.getInvariantName()));
+    }
+
+    public boolean containsGroupWithInvariantName(String invariantName) {
+        return groups != null && groups.stream().anyMatch(gr -> invariantName.equals(gr.getInvariantName()));
+    }
+
+    private Optional<GroupDefinition> getGroupByPredicate(Predicate<GroupDefinition> predicate) {
+        if (groups == null) {
+            return Optional.empty();
+        }
+        return groups.stream()
+                     .filter(predicate)
+                     .findAny();
+    }
+
+    public void setGroups(List<GroupDefinition> groups) {
+        this.groups = groups;
+    }
+
+    public void addGroups(List<GroupDefinition> groupsToAdd) {
+        if (groups == null) {
+            groups = new ArrayList<>();
+        }
+        groups.addAll(groupsToAdd);
+    }
+
+    public Map<String, PolicyDefinition> getPolicies() {
+        return policies;
+    }
+
+    public void setPolicies(Map<String, PolicyDefinition> policies) {
+        this.policies = policies;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((artifacts == null) ? 0 : artifacts.hashCode());
+        result = prime * result + ((categories == null) ? 0 : categories.hashCode());
+        result = prime * result + ((componentMetadataDefinition == null) ? 0 : componentMetadataDefinition.hashCode());
+        result = prime * result + ((deploymentArtifacts == null) ? 0 : deploymentArtifacts.hashCode());
+        result = prime * result + ((capabilities == null) ? 0 : capabilities.hashCode());
+        result = prime * result + ((requirements == null) ? 0 : requirements.hashCode());
+        result = prime * result + ((componentInstances == null) ? 0 : componentInstances.hashCode());
+        result = prime * result
+                + ((componentInstancesProperties == null) ? 0 : componentInstancesProperties.hashCode());
+        result = prime * result
+                + ((componentInstancesAttributes == null) ? 0 : componentInstancesAttributes.hashCode());
+        result = prime * result + ((componentInstancesInputs == null) ? 0 : componentInstancesInputs.hashCode());
+        result = prime * result + ((componentInstancesRelations == null) ? 0 : componentInstancesRelations.hashCode());
+        result = prime * result + ((groups == null) ? 0 : groups.hashCode());
+        result = prime * result + ((policies == null) ? 0 : policies.hashCode());
+        result = prime * result + ((derivedFromGenericType == null) ? 0 : derivedFromGenericType.hashCode());
+        result = prime * result + ((derivedFromGenericVersion == null) ? 0 : derivedFromGenericVersion.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        Component other = (Component) obj;
+        if (artifacts == null) {
+            if (other.artifacts != null) {
+                return false;
+            }
+        }
+        else if (!artifacts.equals(other.artifacts)) {
+            return false;
+        }
+        if (categories == null) {
+            if (other.categories != null) {
+                return false;
+            }
+        }
+        else if (!categories.equals(other.categories)) {
+            return false;
+        }
+        if (componentMetadataDefinition == null) {
+            if (other.componentMetadataDefinition != null) {
+                return false;
+            }
+        }
+        else if (!componentMetadataDefinition.equals(other.componentMetadataDefinition)) {
+            return false;
+        }
+
+        if (deploymentArtifacts == null) {
+            if (other.deploymentArtifacts != null) {
+                return false;
+            }
+        }
+        else if (!deploymentArtifacts.equals(other.deploymentArtifacts)) {
+            return false;
+        }
+
+        if (componentInstances == null) {
+            if (other.componentInstances != null) {
+                return false;
+            }
+        }
+        else if (!componentInstances.equals(other.componentInstances)) {
+            return false;
+        }
+        if (componentInstancesProperties == null) {
+            if (other.componentInstancesProperties != null) {
+                return false;
+            }
+        }
+        else if (!componentInstancesProperties.equals(other.componentInstancesProperties)) {
+            return false;
+        }
+
+        if (!Objects.equals(componentInstancesAttributes, other.componentInstancesAttributes)) {
+            return false;
+        }
+        if (!Objects.equals(componentInstancesInputs, other.componentInstancesInputs)) {
+            return false;
+        }
+        if (componentInstancesRelations == null) {
+            if (other.componentInstancesRelations != null) {
+                return false;
+            }
+        }
+        else if (!componentInstancesRelations.equals(other.componentInstancesRelations)) {
+            return false;
+        }
+        if (requirements == null) {
+            if (other.requirements != null) {
+                return false;
+            }
+        }
+        else if (!requirements.equals(other.requirements)) {
+            return false;
+        }
+        if (capabilities == null) {
+            if (other.capabilities != null) {
+                return false;
+            }
+        }
+        else if (!capabilities.equals(other.capabilities)) {
+            return false;
+        }
+        if (groups == null) {
+            if (other.groups != null) {
+                return false;
+            }
+        }
+        else if (!groups.equals(other.groups)) {
+            return false;
+        }
+        if (policies == null) {
+            if (other.policies != null) {
+                return false;
+            }
+        }
+        else if (!policies.equals(other.policies)) {
+            return false;
+        }
+        if (derivedFromGenericType == null) {
+            if (other.derivedFromGenericType != null) {
+                return false;
+            }
+        }
+        else if (!derivedFromGenericType.equals(other.derivedFromGenericType)) {
+            return false;
+        }
+        if (derivedFromGenericVersion == null) {
+            if (other.derivedFromGenericVersion != null) {
+                return false;
+            }
+        }
+        else if (!derivedFromGenericVersion.equals(other.derivedFromGenericVersion)) {
+            return false;
+        }
+        return true;
+    }
+
+    public void addCategory(String category, String subCategory) {
+        if (category != null || subCategory != null) {
+            if (categories == null) {
+                categories = new ArrayList<>();
+            }
+            CategoryDefinition selectedCategory = null;
+            for (CategoryDefinition categoryDef : categories) {
+                if (categoryDef.getName().equals(category)) {
+                    selectedCategory = categoryDef;
+                }
+            }
+            if (selectedCategory == null) {
+                selectedCategory = new CategoryDefinition();
+                selectedCategory.setName(category);
+                categories.add(selectedCategory);
+            }
+            List<SubCategoryDefinition> subcategories = selectedCategory.getSubcategories();
+            if (subcategories == null) {
+                subcategories = new ArrayList<>();
+                selectedCategory.setSubcategories(subcategories);
+            }
+            SubCategoryDefinition selectedSubcategory = null;
+            for (SubCategoryDefinition subcategory : subcategories) {
+                if (subcategory.getName().equals(subCategory)) {
+                    selectedSubcategory = subcategory;
+                }
+            }
+            if (selectedSubcategory == null) {
+                selectedSubcategory = new SubCategoryDefinition();
+                selectedSubcategory.setName(subCategory);
+                subcategories.add(selectedSubcategory);
+            }
+        }
+    }
+
+    public void addCategory(CategoryDefinition category) {
+        addCategory(category, null);
+    }
+
+    public void addCategory(CategoryDefinition category, SubCategoryDefinition subCategory) {
+        if (categories == null) {
+            categories = new ArrayList<>();
+        }
+        boolean foundCat = false;
+        for (CategoryDefinition cat : categories) {
+            if (cat.getName().equals(category.getName())) {
+                foundCat = true;
+                if (subCategory != null) {
+                    List<SubCategoryDefinition> subcategories = cat.getSubcategories();
+                    if (subcategories == null) {
+                        subcategories = new ArrayList<>();
+                        cat.setSubcategories(subcategories);
+                    }
+                    for (SubCategoryDefinition subcat : subcategories) {
+                        boolean foundSub = false;
+                        if (subcat.getName().equals(subCategory.getName())) {
+                            foundSub = true;
+                        }
+                        if (!foundSub) {
+                            subcategories.add(subCategory);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        if (!foundCat) {
+            if (subCategory != null) {
+                category.addSubCategory(subCategory);
+            }
+            categories.add(category);
+        }
+    }
+
+    public Map<String, List<ComponentInstanceProperty>> getComponentInstancesAttributes() {
+        return componentInstancesAttributes;
+    }
+
+    public void setComponentInstancesAttributes(
+            Map<String, List<ComponentInstanceProperty>> componentInstancesAttributes) {
+        this.componentInstancesAttributes = componentInstancesAttributes;
+    }
+
+    public Map<String, List<ComponentInstanceInput>> getComponentInstancesInputs() {
+        return componentInstancesInputs;
+    }
+
+    public Map<String, List<PropertyDataDefinition>> safeGetGroupsProperties() {
+        if (isEmpty(groups)) {
+            return emptyMap();
+        }
+        return groups.stream()
+              .filter(gr -> Objects.nonNull(gr.getProperties()))
+              .collect(toMap(GroupDataDefinition::getUniqueId,
+                             GroupDataDefinition::getProperties));
+    }
+
+    public Map<String, List<PropertyDataDefinition>> safeGetPolicyProperties() {
+        if (isEmpty(policies)) {
+            return emptyMap();
+        }
+        return policies.values()
+                .stream()
+                .filter(policy -> Objects.nonNull(policy.getProperties()))
+                .collect(toMap(PolicyDataDefinition::getUniqueId,
+                               PolicyDataDefinition::getProperties));
+    }
+
+    public List<ComponentInstanceInput> safeGetComponentInstanceInputsByName(String cmptInstanceName) {
+        List<ComponentInstanceInput> emptyPropsList = emptyList();
+        if (this.componentInstancesInputs == null) {
+            return emptyPropsList;
+        }
+        return this.componentInstances.stream()
+                                      .filter(ci -> ci.getName().equals(cmptInstanceName))
+                                      .map(ComponentInstance::getUniqueId)
+                                      .map(instanceId -> safeGetComponentInstanceEntity(instanceId, this.componentInstancesInputs))
+                                      .findAny()
+                                      .orElse(emptyPropsList);
+    }
+
+    private <T> List<T> safeGetComponentInstanceEntity(String cmptInstanceId, Map<String, List<T>> instanceEntities) {
+        List<T> emptyPropsList = emptyList();
+        if (instanceEntities == null) {
+            return emptyPropsList;
+        }
+        List<T> cmptInstanceProps = instanceEntities.get(cmptInstanceId);
+        return cmptInstanceProps == null ? emptyPropsList : cmptInstanceProps;
+    }
+
+
+    public void setComponentInstancesInputs(Map<String, List<ComponentInstanceInput>> componentInstancesInputs) {
+        this.componentInstancesInputs = componentInstancesInputs;
+    }
+
+    public void setSpecificComponetTypeArtifacts(Map<String, ArtifactDefinition> specificComponentTypeArtifacts) {
+        // Implement where needed
+    }
+
+    public void setMetadataDefinition(ComponentMetadataDefinition metadataDefinition) {
+        this.componentMetadataDefinition = metadataDefinition;
+    }
+
+    public String fetchGenericTypeToscaNameFromConfig() {
+        // Implement where needed
+        return ConfigurationManager.getConfigurationManager()
+                                   .getConfiguration()
+                                   .getGenericAssetNodeTypes()
+                                   .get(this.assetType());
+    }
+
+    public String assetType() {
+        // Implement where needed
+        return this.getComponentType().getValue();
+    }
+
+    public boolean shouldGenerateInputs() {
+        // Implement where needed
+        return true;
+    }
+
+    public boolean deriveFromGeneric() {
+        // Implement where needed
+        return true;
+    }
+
+    public void setDerivedFromGenericInfo(Resource genericType) {
+        derivedFromGenericType = genericType.getToscaResourceName();
+        derivedFromGenericVersion = genericType.getVersion();
+    }
+
+    public boolean isTopologyTemplate() {
+        return ToscaElementTypeEnum.TOPOLOGY_TEMPLATE.getValue().equals(toscaType);
+    }
+
+    public String getToscaType() {
+        return toscaType;
+    }
+
+    public void setToscaType(String toscaType) {
+        this.toscaType = toscaType;
+    }
+
+    public List<AdditionalInformationDefinition> getAdditionalInformation() {
+        return additionalInformation;
+    }
+
+    public void setAdditionalInformation(List<AdditionalInformationDefinition> additionalInformation) {
+        this.additionalInformation = additionalInformation;
+    }
+
+    public PolicyDefinition getPolicyById(String id) {
+        return policies != null ? policies.get(id) : null;
+    }
+
+    public List<PolicyDefinition> resolvePoliciesList() {
+        if (policies == null) {
+            return emptyList();
+        }
+        return new ArrayList<>(policies.values());
+    }
+
+    public List<PolicyDefinition> resolvePoliciesContainingTarget(String targetId, PolicyTargetType targetType) {
+        Predicate<PolicyDefinition> containsTarget = policy -> policy.containsTarget(targetId, targetType);
+        return resolvePoliciesByPredicate(containsTarget);
+    }
+
+    private List<PolicyDefinition> resolvePoliciesByPredicate(Predicate<PolicyDefinition> policyPredicate) {
+        if (policies == null) {
+            return emptyList();
+        }
+        return policies.values().stream()
+                       .filter(policyPredicate)
+                       .collect(Collectors.toList());
+    }
+
+    public List<GroupDefinition> resolveGroupsByMember(String instanceId) {
+        if (groups == null) {
+            return emptyList();
+        }
+        return groups.stream()
+                     .filter(group -> group.containsInstanceAsMember(instanceId))
+                     .collect(Collectors.toList());
+    }
+
+    public String getActualComponentType() {
+        return componentMetadataDefinition.getMetadataDataDefinition().getActualComponentType();
+    }
+
+    public Boolean isArchived() { return componentMetadataDefinition.getMetadataDataDefinition().isArchived(); }
+
+    public void setArchived(Boolean archived) { componentMetadataDefinition.getMetadataDataDefinition().setArchived(archived); }
+
+    public Long getArchiveTime() { return componentMetadataDefinition.getMetadataDataDefinition().getArchiveTime(); }
+
+    public void setArchiveTime(Long archiveTime) { componentMetadataDefinition.getMetadataDataDefinition().setArchiveTime(archiveTime); }
+
+    public Boolean isVspArchived() { return componentMetadataDefinition.getMetadataDataDefinition().isVspArchived();	}
+
+    public void setVspArchived(Boolean vspArchived) { componentMetadataDefinition.getMetadataDataDefinition().setVspArchived(vspArchived); }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentDependency.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentDependency.java
new file mode 100644
index 0000000..6a9e886
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentDependency.java
@@ -0,0 +1,94 @@
+package org.openecomp.sdc.be.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class ComponentDependency {
+    private String name;
+    private String version;
+    private String uniqueId;
+    private String type;
+    private String icon;
+    private String state;
+    private List<String> instanceNames;
+    
+    private List<ComponentDependency> dependencies;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getUniqueId() {
+        return uniqueId;
+    }
+
+    public void setUniqueId(String uniqueId) {
+        this.uniqueId = uniqueId;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public List<ComponentDependency> getDependencies() {
+        return dependencies;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public List<String> getInstanceNames() {
+        return instanceNames;
+    }
+
+    public void setInstanceNames(List<String> instanceNames) {
+        this.instanceNames = instanceNames;
+    }
+
+    public void setDependencies(List<ComponentDependency> dependencies) {
+        this.dependencies = dependencies;
+    }
+    public void addDependencies(List<ComponentDependency> dependencies) {
+        if ( this.dependencies == null ){
+            this.dependencies = new ArrayList<>();
+        }
+        this.dependencies.addAll(dependencies);
+   }
+
+    public void addDependency(ComponentDependency dependency){
+        if ( dependencies == null ){
+            dependencies = new ArrayList<>();
+        }
+        dependencies.add(dependency);
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.java
index 3db3131..306992d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.java
@@ -20,35 +20,34 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
+import org.apache.commons.lang3.tuple.Pair;
+
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.collections.MapUtils;
-import org.apache.commons.lang3.tuple.Pair;
+import static org.apache.commons.collections.MapUtils.isNotEmpty;
 
-public class ComponentInstInputsMap implements Serializable {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 1136631343963488131L;
+public class ComponentInstInputsMap {
 
     private Map<String, List<ComponentInstancePropInput>> componentInstanceInputsMap;
     private Map<String, List<ComponentInstancePropInput>> componentInstanceProperties;
     private Map<String, List<ComponentInstancePropInput>> policyProperties;
+    private Map<String, List<ComponentInstancePropInput>> groupProperties;
 
     public Pair<String, List<ComponentInstancePropInput>> resolvePropertiesToDeclare() {
-        if (!MapUtils.isEmpty(componentInstanceInputsMap)) {
+        if (isNotEmpty(componentInstanceInputsMap)) {
             return singleMapEntry(componentInstanceInputsMap);
         }
-        if (!MapUtils.isEmpty(componentInstanceProperties)) {
+        if (isNotEmpty(componentInstanceProperties)) {
             return singleMapEntry(componentInstanceProperties);
         }
-        if (!MapUtils.isEmpty(policyProperties)) {
+        if (isNotEmpty(policyProperties)) {
             return singleMapEntry(policyProperties);
         }
-        throw new IllegalStateException("there are no properties selected for deceleration");
+        if (isNotEmpty(groupProperties)) {
+            return singleMapEntry(groupProperties);
+        }
+        throw new IllegalStateException("there are no properties selected for declaration");
     }
 
     private Pair<String, List<ComponentInstancePropInput>> singleMapEntry(Map<String, List<ComponentInstancePropInput>> propertiesMap) {
@@ -79,4 +78,15 @@
     public void setPolicyProperties(Map<String, List<ComponentInstancePropInput>> policyProperties) {
         this.policyProperties = policyProperties;
     }
+
+    public Map<String, List<ComponentInstancePropInput>> getGroupProperties() {
+        return groupProperties;
+    }
+
+    public void setGroupProperties(Map<String, List<ComponentInstancePropInput>> groupProperties) {
+        this.groupProperties = groupProperties;
+    }
+
+
+
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java
index e80f306..4a62286 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java
@@ -20,21 +20,15 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertiesOwner;
 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
 
-public class ComponentInstance extends ComponentInstanceDataDefinition implements Serializable, PropertiesOwner {
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 
-    /**
-     *
-     */
-    private static final long serialVersionUID = 6721465693884621223L;
+public class ComponentInstance extends ComponentInstanceDataDefinition implements PropertiesOwner {
 
     private Map<String, List<CapabilityDefinition>> capabilities;
     private Map<String, List<RequirementDefinition>> requirements;
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.java
index 1ffbede..d97db3f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.java
@@ -20,108 +20,94 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
 
+import java.util.List;
+
 public class ComponentInstanceInput extends InputDefinition implements IComponentInstanceConnectedElement, IPropertyInputCommon {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -3937554584759816724L;
+    /**
+     * The unique id of the property value on graph
+     */
+    private String valueUniqueUid;
 
+    private List<String> path = null;
 
-	/**
-	 * The unique id of the property value on graph
-	 */
-	private String valueUniqueUid;
+    private List<PropertyRule> rules = null;
+    private String componentInstanceName;
+    private String componentInstanceId;
 
-	private List<String> path = null;
+    public ComponentInstanceInput() {
+        super();
+    }
 
-	private List<PropertyRule> rules = null;
-	private String componentInstanceName;
-	private String componentInstanceId;
+    public ComponentInstanceInput(PropertyDataDefinition curPropertyDef, String inputId, String value,
+            String valueUniqueUid) {
+        super(curPropertyDef);
+        setInputId(inputId);
+        setValue(value);
+        this.valueUniqueUid = valueUniqueUid;
+    }
 
-	public ComponentInstanceInput() {
-		super();
-	}
+    public ComponentInstanceInput(InputDefinition pd, String value, String valueUniqueUid) {
+        super(pd);
 
-	public ComponentInstanceInput(PropertyDataDefinition curPropertyDef, String inputId, String value,
-			String valueUniqueUid) {
-		super(curPropertyDef);
-		setInputId(inputId);
-		setValue(value);
-		this.valueUniqueUid = valueUniqueUid;
-	}
+        setValue(value);
+        this.valueUniqueUid = valueUniqueUid;
+    }
 
-	public ComponentInstanceInput(InputDefinition pd, String value, String valueUniqueUid) {
-		super(pd);
+    public ComponentInstanceInput(PropertyDataDefinition propertyDefinition) {
+        super(propertyDefinition);
+        if(propertyDefinition.getGetInputValues() != null && !propertyDefinition.getGetInputValues().isEmpty()){
+            setInputId(propertyDefinition.getGetInputValues().get(0).getInputId());
+        }
+    }
 
-		setValue(value);
-		this.valueUniqueUid = valueUniqueUid;
-	}
+    public String getComponentInstanceName() {
+        return componentInstanceName;
+    }
 
-	public ComponentInstanceInput(PropertyDataDefinition propertyDefinition) {
-		super(propertyDefinition);
-		if(propertyDefinition.getGetInputValues() != null && !propertyDefinition.getGetInputValues().isEmpty()){
-			setInputId(propertyDefinition.getGetInputValues().get(0).getInputId());
-		}
-	}
+    public void setComponentInstanceName(String componentInstanceName) {
+        this.componentInstanceName = componentInstanceName;
+    }
 
-	public String getComponentInstanceName() {
-		return componentInstanceName;
-	}
+    public String getComponentInstanceId() {
+        return componentInstanceId;
+    }
 
-	public void setComponentInstanceName(String componentInstanceName) {
-		this.componentInstanceName = componentInstanceName;
-	}
+    public void setComponentInstanceId(String componentInstanceId) {
+        this.componentInstanceId = componentInstanceId;
+    }
 
-	public String getComponentInstanceId() {
-		return componentInstanceId;
-	}
+    public String getValueUniqueUid() {
+        return valueUniqueUid;
+    }
 
-	public void setComponentInstanceId(String componentInstanceId) {
-		this.componentInstanceId = componentInstanceId;
-	}
+    public void setValueUniqueUid(String valueUniqueUid) {
+        this.valueUniqueUid = valueUniqueUid;
+    }
 
-	public String getValueUniqueUid() {
-		return valueUniqueUid;
-	}
+    public List<String> getPath() {
+        return path;
+    }
 
-	public void setValueUniqueUid(String valueUniqueUid) {
-		this.valueUniqueUid = valueUniqueUid;
-	}
+    public void setPath(List<String> path) {
+        this.path = path;
+    }
 
-	/*public boolean isDefinition() {
-		return definition;
-	}
+    public List<PropertyRule> getRules() {
+        return rules;
+    }
 
-	public void setDefinition(boolean definition) {
-		this.definition = definition;
-	}*/
+    public void setRules(List<PropertyRule> rules) {
+        this.rules = rules;
+    }
 
-	public List<String> getPath() {
-		return path;
-	}
-
-	public void setPath(List<String> path) {
-		this.path = path;
-	}
-
-	public List<PropertyRule> getRules() {
-		return rules;
-	}
-
-	public void setRules(List<PropertyRule> rules) {
-		this.rules = rules;
-	}
-
-	@Override
-	public String toString() {
-		return "ComponentInstanceInput [ " + super.toString() + " , value=" + getValue() + ", valueUniqueUid = "
-				+ valueUniqueUid + " , rules=" + rules + " , path=" + path + " ]";
-	}
+    @Override
+    public String toString() {
+        return "ComponentInstanceInput [ " + super.toString() + " , value=" + getValue() + ", valueUniqueUid = "
+                + valueUniqueUid + " , rules=" + rules + " , path=" + path + " ]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstancePropInput.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstancePropInput.java
index ace8381..80cf424 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstancePropInput.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstancePropInput.java
@@ -20,45 +20,38 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
+public class ComponentInstancePropInput extends ComponentInstanceProperty {
 
-public class ComponentInstancePropInput extends ComponentInstanceProperty implements Serializable{
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -7991205190252140617L;
-	
-	
-	private String propertiesName; 
-	private PropertyDefinition input;
-	
-	public ComponentInstancePropInput() {
-		super();
-	}
-	
-	public ComponentInstancePropInput(ComponentInstanceProperty p) {
-		super(p);
-	}
-	
-	public String getPropertiesName() {
-		return propertiesName;
-	}
-	public void setPropertiesName(String propertiesName) {
-		this.propertiesName = propertiesName;
-	}
-	public PropertyDefinition getInput() {
-		return input;
-	}
-	public void setInput(PropertyDefinition input) {
-		this.input = input;
-	} 
-	
-	public String[] getParsedPropNames(){
-		String[] tokens = null;
-		if(propertiesName != null && !propertiesName.isEmpty()){
-			tokens = propertiesName.split("#");
-		}
-		return tokens;
-	}
+    private String propertiesName;
+    private PropertyDefinition input;
+
+    public ComponentInstancePropInput() {
+        super();
+    }
+
+    public ComponentInstancePropInput(ComponentInstanceProperty p) {
+        super(p);
+    }
+
+    public String getPropertiesName() {
+        return propertiesName;
+    }
+    public void setPropertiesName(String propertiesName) {
+        this.propertiesName = propertiesName;
+    }
+    public PropertyDefinition getInput() {
+        return input;
+    }
+    public void setInput(PropertyDefinition input) {
+        this.input = input;
+    }
+
+    public String[] getParsedPropNames(){
+        String[] tokens = null;
+        if(propertiesName != null && !propertiesName.isEmpty()){
+            tokens = propertiesName.split("#");
+        }
+        return tokens;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.java
index 26c5c02..459f7a1 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.java
@@ -20,112 +20,106 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
 
-public class ComponentInstanceProperty extends PropertyDefinition implements IComponentInstanceConnectedElement, IPropertyInputCommon, Serializable {
+import java.util.List;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -6559573536869242691L;
+public class ComponentInstanceProperty extends PropertyDefinition implements IComponentInstanceConnectedElement, IPropertyInputCommon {
 
-	/**
-	 * Value of property
-	 */
+    /**
+     * The unique id of the property value on graph
+     */
+    private String valueUniqueUid;
+
+    private List<String> path;
+
+    private List<PropertyRule> rules ;
+
+
+    private String componentInstanceName;
+
+    private String componentInstanceId;
+
+    public String getComponentInstanceName() {
+        return componentInstanceName;
+    }
+
+    public void setComponentInstanceName(String componentInstanceName) {
+        this.componentInstanceName = componentInstanceName;
+    }
+
+    public String getComponentInstanceId() {
+        return componentInstanceId;
+    }
+
+    public void setComponentInstanceId(String componentInstanceId) {
+        this.componentInstanceId = componentInstanceId;
+    }
+
+    public ComponentInstanceProperty() {
+        super();
+    }
+    public ComponentInstanceProperty(PropertyDataDefinition pd) {
+        super(pd);
+    }
+
+    public ComponentInstanceProperty(PropertyDefinition pd) {
+        super(pd);
+    }
+
+    public ComponentInstanceProperty(PropertyDefinition pd, String value, String valueUniqueUid) {
+        super(pd);
+
+        this.setValue(value);
+        this.valueUniqueUid = valueUniqueUid;
+    }
+
+    public ComponentInstanceProperty(Boolean hidden, PropertyDefinition pd, String valueUniqueUid) {
+        super(pd);
+
+        this.hidden = hidden;
+        this.valueUniqueUid = valueUniqueUid;
+        setParentUniqueId(pd.getParentUniqueId());
+    }
+
+
+
+    public String getValueUniqueUid() {
+        return valueUniqueUid;
+    }
+
+    public void setValueUniqueUid(String valueUniqueUid) {
+        this.valueUniqueUid = valueUniqueUid;
+    }
+
+
+    public List<String> getPath() {
+        return path;
+    }
+
+    public void setPath(List<String> path) {
+        this.path = path;
+    }
+
+    public List<PropertyRule> getRules() {
+        return rules;
+    }
+
+    public void setRules(List<PropertyRule> rules) {
+        this.rules = rules;
+    }
+
+
+    @Override
+    public String toString() {
+        return "ComponentInstanceProperty [ " + super.toString() + " , value=" + getValue() + ", valueUniqueUid = " + valueUniqueUid + " , rules=" + rules + " , path=" + path + " ]";
+    }
 	
-
-	/**
-	 * The unique id of the property value on graph
-	 */
-	private String valueUniqueUid;
-
-	private List<String> path = null;
-
-	private List<PropertyRule> rules = null;
-
-	
-	
-	private String componentInstanceName;
-	
-	private String componentInstanceId;
-	
-	public String getComponentInstanceName() {
-		return componentInstanceName;
-	}
-
-	public void setComponentInstanceName(String componentInstanceName) {
-		this.componentInstanceName = componentInstanceName;
-	}
-
-	public String getComponentInstanceId() {
-		return componentInstanceId;
-	}
-
-	public void setComponentInstanceId(String componentInstanceId) {
-		this.componentInstanceId = componentInstanceId;
-	}
-
-	public ComponentInstanceProperty() {
-		super();
-	}
-	public ComponentInstanceProperty(PropertyDataDefinition pd) {
-		super(pd);
-	}
-	
-	public ComponentInstanceProperty(PropertyDefinition pd) {
-		super(pd);
-	}
-
-	public ComponentInstanceProperty(PropertyDefinition pd, String value, String valueUniqueUid) {
-		super(pd);
-
-		this.setValue(value);
-		this.valueUniqueUid = valueUniqueUid;
-	}
-	
-	public ComponentInstanceProperty(Boolean hidden, PropertyDefinition pd, String valueUniqueUid) {
-		super(pd);
-
-		this.hidden = hidden;
-		this.valueUniqueUid = valueUniqueUid;
-		setParentUniqueId(pd.getParentUniqueId());
-	}
-
-	
-
-	public String getValueUniqueUid() {
-		return valueUniqueUid;
-	}
-
-	public void setValueUniqueUid(String valueUniqueUid) {
-		this.valueUniqueUid = valueUniqueUid;
-	}
-
-
-	public List<String> getPath() {
-		return path;
-	}
-
-	public void setPath(List<String> path) {
-		this.path = path;
-	}
-
-	public List<PropertyRule> getRules() {
-		return rules;
-	}
-
-	public void setRules(List<PropertyRule> rules) {
-		this.rules = rules;
-	}
-
-	
-	@Override
-	public String toString() {
-		return "ComponentInstanceProperty [ " + super.toString() + " , value=" + getValue() + ", valueUniqueUid = " + valueUniqueUid + " , rules=" + rules + " , path=" + path + " ]";
+	public void updateCapabilityProperty(ComponentInstanceProperty property) {
+		if(property != null && property.getValue() != null){
+			setValue(property.getValue());
+		}
 	}
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.java
index da3947b..a126a74 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.java
@@ -20,55 +20,48 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-
 import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition;
 
-public class ComponentMetadataDefinition implements Serializable {
+public class ComponentMetadataDefinition {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 3570763790267255590L;
+    protected ComponentMetadataDataDefinition componentMetadataDataDefinition;
 
-	protected ComponentMetadataDataDefinition componentMetadataDataDefinition;
+    public ComponentMetadataDefinition() {
 
-	public ComponentMetadataDefinition() {
+    }
 
-	}
+    public ComponentMetadataDefinition(ComponentMetadataDataDefinition component) {
+        this.componentMetadataDataDefinition = component;
+    }
 
-	public ComponentMetadataDefinition(ComponentMetadataDataDefinition component) {
-		this.componentMetadataDataDefinition = component;
-	}
+    public ComponentMetadataDataDefinition getMetadataDataDefinition() {
+        return this.componentMetadataDataDefinition;
+    }
 
-	public ComponentMetadataDataDefinition getMetadataDataDefinition() {
-		return this.componentMetadataDataDefinition;
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result
+                + ((componentMetadataDataDefinition == null) ? 0 : componentMetadataDataDefinition.hashCode());
+        return result;
+    }
 
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result
-				+ ((componentMetadataDataDefinition == null) ? 0 : componentMetadataDataDefinition.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		ComponentMetadataDefinition other = (ComponentMetadataDefinition) obj;
-		if (componentMetadataDataDefinition == null) {
-			if (other.componentMetadataDataDefinition != null)
-				return false;
-		} else if (!componentMetadataDataDefinition.equals(other.componentMetadataDataDefinition))
-			return false;
-		return true;
-	}
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ComponentMetadataDefinition other = (ComponentMetadataDefinition) obj;
+        if (componentMetadataDataDefinition == null) {
+            if (other.componentMetadataDataDefinition != null)
+                return false;
+        } else if (!componentMetadataDataDefinition.equals(other.componentMetadataDataDefinition))
+            return false;
+        return true;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java
index 769aa8a..0cff11e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java
@@ -7,9 +7,9 @@
  * 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.
@@ -20,446 +20,399 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 
+import java.util.List;
+
 public class ComponentParametersView {
 
-	boolean ignoreUsers = false;
-	boolean ignoreGroups = false;
-	boolean ignoreComponentInstances = false;
-	boolean ignoreComponentInstancesProperties = false;
-	boolean ignoreProperties = false;
-	boolean ignoreCapabilities = false;
-	boolean ignoreRequirements = false;
-	boolean ignoreCategories = false;
-	boolean ignoreAllVersions = false;
-	boolean ignoreAdditionalInformation = false;
-	boolean ignoreArtifacts = false;
-	boolean ignoreInterfaces = false;
-	boolean ignoreDerivedFrom = false;
-	boolean ignoreAttributesFrom = false;
-	boolean ignoreComponentInstancesAttributesFrom = false;
-	boolean ignoreInputs = false;
-	boolean ignoreComponentInstancesInputs = false;
-	boolean ignoreCapabiltyProperties = true;
-	boolean ignoreServicePath = true;
-	boolean ignorePolicies = false;
+    private boolean ignoreUsers = false;
+    private boolean ignoreGroups = false;
+    private boolean ignoreComponentInstances = false;
+    private boolean ignoreComponentInstancesProperties = false;
+    private boolean ignoreProperties = false;
+    private boolean ignoreCapabilities = false;
+    private boolean ignoreRequirements = false;
+    private boolean ignoreCategories = false;
+    private boolean ignoreAllVersions = false;
+    private boolean ignoreAdditionalInformation = false;
+    private boolean ignoreArtifacts = false;
+    private boolean ignoreInterfaces = false;
+    private boolean ignoreDerivedFrom = false;
+    private boolean ignoreAttributesFrom = false;
+    private boolean ignoreComponentInstancesAttributesFrom = false;
+    private boolean ignoreInputs = false;
+    private boolean ignoreComponentInstancesInputs = false;
+    private boolean ignoreCapabiltyProperties = true;
+    private boolean ignoreServicePath = true;
+    private boolean ignorePolicies = false;
 
-	public ComponentParametersView() {
-	}
+    public ComponentParametersView() {
+    }
 
-	public ComponentParametersView(boolean setAllToIgnore) {
-		this();
-		if(setAllToIgnore){
-			this.disableAll();
-		}
-	}
+    public ComponentParametersView(boolean setAllToIgnore) {
+        this();
+        if (setAllToIgnore) {
+            this.disableAll();
+        }
+    }
 
-	public ComponentParametersView(List<String> filters) {
-		this(true);
+    public ComponentParametersView(List<String> filters) {
+        this(true);
 
-		for(String fieldName: filters) {
-			switch (ComponentFieldsEnum.findByValue(fieldName)) {
-			case PROPERTIES:
-				this.setIgnoreProperties(false);
-				break;
-			case INPUTS:
-				this.setIgnoreInputs(false);;
-				break;
-			case USERS:
-				this.setIgnoreUsers(false);
-				break;
-			case CATEGORIES:
-				this.setIgnoreCategories(false);
-				break;
-			case METADATA:
-				this.setIgnoreUsers(false);
-				this.setIgnoreCategories(false);
-				this.setIgnoreAllVersions(false);
-				this.setIgnoreDerivedFrom(false);
-				break;
-			case GROUPS:
-				this.setIgnoreGroups(false);
-				break;
-			case COMPONENT_INSTANCES:
-				this.setIgnoreComponentInstances(false);
-				this.setIgnoreCapabilities(false);
-				this.setIgnoreRequirements(false);
-				break;
-			case COMPONENT_INSTANCES_PROPERTIES:
-				this.setIgnoreComponentInstances(false); //we need this in order to get the calculate capabilities requirements
-				this.setIgnoreComponentInstancesProperties(false);
-				break;
-			case CAPABILITIES:
-				this.setIgnoreComponentInstances(false);//we need this in order to get the calculate capabilities requirements
-				this.setIgnoreCapabilities(false);
-				break;
-			case REQUIREMENTS:
-				this.setIgnoreComponentInstances(false);
-				this.setIgnoreRequirements(false);
-				break;
-			case ALL_VERSIONS:
-				this.setIgnoreAllVersions(false);
-				break;
-			case ADDITIONAL_INFORMATION:
-				this.setIgnoreAdditionalInformation(false);
-				break;
-			case ARTIFACTS:
-			case DEPLOYMENT_ARTIFACTS:
-			case TOSCA_ARTIFACTS:
-			case SERVICE_API_ARTIFACTS:
-				this.setIgnoreArtifacts(false);
-				break;
-			case INTERFACES:
-				this.setIgnoreInterfaces(false);
-				break;
-			case DERIVED_FROM:
-				this.setIgnoreDerivedFrom(false);
-				break;
-			case ATTRIBUTES:
-				this.setIgnoreAttributesFrom(false);
-				break;
-			case COMPONENT_INSTANCES_ATTRIBUTES:
-				this.setIgnoreComponentInstances(false);
-				this.setIgnoreComponentInstancesAttributesFrom(false);
-				break;
-			case COMPONENT_INSTANCE_INPUTS:
-				this.setIgnoreComponentInstances(false);
-				this.setIgnoreComponentInstancesInputs(false);
-				break;
-			case INSTANCE_CAPABILTY_PROPERTIES:
-				this.setIgnoreCapabiltyProperties(false);
-				break;
-			case FORWARDING_PATHS:
-				this.setIgnoreForwardingPath(false);
-				break;
-			case POLICIES:
-				this.setIgnorePolicies(false);
-				break;
-			default:
-				break;
-			}
+        for (String fieldName : filters) {
+            switch (ComponentFieldsEnum.findByValue(fieldName)) {
+                case PROPERTIES:
+                    this.setIgnoreProperties(false);
+                    break;
+                case INPUTS:
+                    this.setIgnoreInputs(false);
+                    break;
+                case USERS:
+                    this.setIgnoreUsers(false);
+                    break;
+                case CATEGORIES:
+                    this.setIgnoreCategories(false);
+                    break;
+                case METADATA:
+                    this.setIgnoreUsers(false);
+                    this.setIgnoreCategories(false);
+                    this.setIgnoreAllVersions(false);
+                    this.setIgnoreDerivedFrom(false);
+                    break;
+                case GROUPS:
+                case NON_EXCLUDED_GROUPS:
+                    this.setIgnoreGroups(false);
+                    break;
+                case COMPONENT_INSTANCES:
+                    this.setIgnoreComponentInstances(false);
+                    this.setIgnoreCapabilities(false);
+                    this.setIgnoreRequirements(false);
+                    break;
+                case COMPONENT_INSTANCES_PROPERTIES:
+                    this.setIgnoreComponentInstances(false); //we need this in order to get the calculate capabilities requirements
+                    this.setIgnoreComponentInstancesProperties(false);
+                    break;
+                case CAPABILITIES:
+                    this.setIgnoreComponentInstances(false);//we need this in order to get the calculate capabilities requirements
+                    this.setIgnoreCapabilities(false);
+                    break;
+                case REQUIREMENTS:
+                    this.setIgnoreComponentInstances(false);
+                    this.setIgnoreRequirements(false);
+                    break;
+                case ALL_VERSIONS:
+                    this.setIgnoreAllVersions(false);
+                    break;
+                case ADDITIONAL_INFORMATION:
+                    this.setIgnoreAdditionalInformation(false);
+                    break;
+                case ARTIFACTS:
+                case DEPLOYMENT_ARTIFACTS:
+                case TOSCA_ARTIFACTS:
+                case SERVICE_API_ARTIFACTS:
+                    this.setIgnoreArtifacts(false);
+                    break;
+                case INTERFACES:
+                    this.setIgnoreInterfaces(false);
+                    break;
+                case DERIVED_FROM:
+                    this.setIgnoreDerivedFrom(false);
+                    break;
+                case ATTRIBUTES:
+                    this.setIgnoreAttributesFrom(false);
+                    break;
+                case COMPONENT_INSTANCES_ATTRIBUTES:
+                    this.setIgnoreComponentInstances(false);
+                    this.setIgnoreComponentInstancesAttributesFrom(false);
+                    break;
+                case COMPONENT_INSTANCE_INPUTS:
+                    this.setIgnoreComponentInstances(false);
+                    this.setIgnoreComponentInstancesInputs(false);
+                    break;
+                case INSTANCE_CAPABILTY_PROPERTIES:
+                    this.setIgnoreCapabiltyProperties(false);
+                    break;
+                case FORWARDING_PATHS:
+                    this.setIgnoreForwardingPath(false);
+                    break;
+                case POLICIES:
+                case NON_EXCLUDED_POLICIES:
+                    this.setIgnorePolicies(false);
+                    break;
+                default:
+                    break;
+            }
 
-		}
-	}
+        }
+    }
 
-	///////////////////////////////////////////////////////////////
-	// When adding new member, please update the filter method.
-	///////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////
+    // When adding new member, please update the filter method.
+    ///////////////////////////////////////////////////////////////
 
-	public Component filter(Component component, ComponentTypeEnum componentType) {
+    public Component filter(Component component, ComponentTypeEnum componentType) {
 
-		if (ignoreUsers) {
-			component.setCreatorUserId(null);
-			component.setCreatorFullName(null);
-			component.setLastUpdaterUserId(null);
-			component.setLastUpdaterFullName(null);
-		}
+        if (ignoreUsers) {
+            component.setCreatorUserId(null);
+            component.setCreatorFullName(null);
+            component.setLastUpdaterUserId(null);
+            component.setLastUpdaterFullName(null);
+        }
+        if (ignoreGroups) {
+            component.setGroups(null);
+        }
+        if (ignoreComponentInstances) {
+            component.setComponentInstances(null);
+            component.setComponentInstancesRelations(null);
+        }
+        if (ignoreComponentInstancesProperties) {
+            component.setComponentInstancesProperties(null);
+        }
+        if (ignoreProperties && componentType == ComponentTypeEnum.RESOURCE) {
+            ((Resource) component).setProperties(null);
+        }
+        if (ignoreCapabilities) {
+            component.setCapabilities(null);
+        }
+        if (ignoreRequirements) {
+            component.setRequirements(null);
+        }
+        if (ignoreCategories) {
+            component.setCategories(null);
+        }
+        if (ignoreAllVersions) {
+            component.setAllVersions(null);
+        }
+        if (ignoreAdditionalInformation && componentType == ComponentTypeEnum.RESOURCE) {
+            ((Resource) component).setAdditionalInformation(null);
+        }
+        if (ignoreArtifacts) {
+            component.setArtifacts(null);
+            component.setSpecificComponetTypeArtifacts(null);
+            component.setDeploymentArtifacts(null);
+            component.setToscaArtifacts(null);
+        }
+        if (ignoreInterfaces && componentType == ComponentTypeEnum.RESOURCE) {
+            ((Resource) component).setInterfaces(null);
+        }
+        if (ignoreDerivedFrom && componentType == ComponentTypeEnum.RESOURCE) {
+            ((Resource) component).setDerivedFrom(null);
+        }
+        if (ignoreAttributesFrom && componentType == ComponentTypeEnum.RESOURCE) {
+            ((Resource) component).setAttributes(null);
+        }
+        if (ignoreComponentInstancesAttributesFrom) {
+            component.setComponentInstancesAttributes(null);
+        }
+        if (ignoreInputs) {
+            component.setInputs(null);
+        }
+        if (ignoreComponentInstancesInputs) {
+            component.setComponentInstancesInputs(null);
+        }
+        if (ignoreServicePath && componentType == ComponentTypeEnum.SERVICE) {
+            ((Service) component).setForwardingPaths(null);
+        }
+        return component;
+    }
 
-		if (ignoreGroups) {
-			component.setGroups(null);
-		}
+    public void disableAll() {
+        ignoreUsers = true;
+        ignoreGroups = true;
+        ignorePolicies = true;
+        ignoreComponentInstances = true;
+        ignoreComponentInstancesProperties = true;
+        ignoreProperties = true;
+        ignoreCapabilities = true;
+        ignoreRequirements = true;
+        ignoreCategories = true;
+        ignoreAllVersions = true;
+        ignoreAdditionalInformation = true;
+        ignoreArtifacts = true;
+        ignoreInterfaces = true;
+        ignoreDerivedFrom = true;
+        ignoreAttributesFrom = true;
+        ignoreInputs = true;
+        ignoreComponentInstancesAttributesFrom = true;
+        ignoreComponentInstancesInputs = true;
+        ignoreCapabiltyProperties = true;
+        ignoreServicePath = true;
+    }
 
-		if (ignoreComponentInstances) {
-			component.setComponentInstances(null);
-			component.setComponentInstancesRelations(null);
-		}
+    public boolean isIgnoreGroups() {
+        return ignoreGroups;
+    }
 
-		if (ignoreComponentInstancesProperties) {
-			component.setComponentInstancesProperties(null);
-		}
+    public void setIgnoreGroups(boolean ignoreGroups) {
+        this.ignoreGroups = ignoreGroups;
+        if (!ignoreGroups) {
+            this.ignoreCapabiltyProperties = ignoreGroups;
+            this.ignoreCapabilities = ignoreGroups;
+        }
+    }
 
-		if (ignoreProperties) {
-			switch (componentType) {
-			case RESOURCE:
-				((Resource) component).setProperties(null);
-				break;
-			default:
-				break;
-			}
-		}
+    public boolean isIgnoreComponentInstances() {
+        return ignoreComponentInstances;
+    }
 
-		if (ignoreCapabilities) {
-			component.setCapabilities(null);
-		}
-
-		if (ignoreRequirements) {
-			component.setRequirements(null);
-		}
-
-		if (ignoreCategories) {
-			component.setCategories(null);
-		}
-
-		if (ignoreAllVersions) {
-			component.setAllVersions(null);
-		}
-
-		if (ignoreAdditionalInformation) {
-			switch (componentType) {
-			case RESOURCE:
-				((Resource) component).setAdditionalInformation(null);
-				break;
-			default:
-				break;
-			}
-		}
-
-		if (ignoreArtifacts) {
-			component.setArtifacts(null);
-			component.setSpecificComponetTypeArtifacts(null);
-			component.setDeploymentArtifacts(null);
-			component.setToscaArtifacts(null);
-		}
-
-		if (ignoreInterfaces) {
-			switch (componentType) {
-			case RESOURCE:
-				((Resource) component).setInterfaces(null);
-				break;
-			default:
-				break;
-			}
-		}
-
-		if (ignoreDerivedFrom) {
-			switch (componentType) {
-			case RESOURCE:
-				((Resource) component).setDerivedFrom(null);
-				break;
-			default:
-				break;
-			}
-		}
-
-		if (ignoreAttributesFrom) {
-			switch (componentType) {
-			case RESOURCE:
-				((Resource) component).setAttributes(null);
-				break;
-			default:
-				break;
-			}
-		}
-
-		if (ignoreComponentInstancesAttributesFrom) {
-			component.setComponentInstancesAttributes(null);
-		}
-
-		if (ignoreInputs) {
-			component.setInputs(null);
-		}
-
-		if (ignoreComponentInstancesInputs) {
-			component.setComponentInstancesInputs(null);
-		}
-
-		if (ignoreServicePath){
-			switch (componentType) {
-				case SERVICE:
-					((Service) component).setForwardingPaths(null);
-					break;
-				default:
-					break;
-			}
-		}
-		return component;
-
-	}
-
-	public void disableAll() {
-		ignoreUsers = true;
-		ignoreGroups = true;
-		ignoreComponentInstances = true;
-		ignoreComponentInstancesProperties = true;
-		ignoreProperties = true;
-		ignoreCapabilities = true;
-		ignoreRequirements = true;
-		ignoreCategories = true;
-		ignoreAllVersions = true;
-		ignoreAdditionalInformation = true;
-		ignoreArtifacts = true;
-		ignoreInterfaces = true;
-		ignoreDerivedFrom = true;
-		ignoreAttributesFrom = true;
-		ignoreInputs = true;
-		ignoreComponentInstancesAttributesFrom = true;
-		ignoreComponentInstancesInputs = true;
-		ignoreCapabiltyProperties = true;
-		ignoreServicePath = true;
-	}
-
-	public boolean isIgnoreGroups() {
-		return ignoreGroups;
-	}
-
-	public void setIgnoreGroups(boolean ignoreGroups) {
-		this.ignoreGroups = ignoreGroups;
-	}
+    public void setIgnoreComponentInstances(boolean ignoreComponentInstances) {
+        this.ignoreComponentInstances = ignoreComponentInstances;
+    }
 
-	public boolean isIgnoreComponentInstances() {
-		return ignoreComponentInstances;
-	}
+    public boolean isIgnoreProperties() {
+        return ignoreProperties;
+    }
 
-	public void setIgnoreComponentInstances(boolean ignoreComponentInstances) {
-		this.ignoreComponentInstances = ignoreComponentInstances;
-	}
+    public void setIgnoreProperties(boolean ignoreProperties) {
+        this.ignoreProperties = ignoreProperties;
+    }
 
-	public boolean isIgnoreProperties() {
-		return ignoreProperties;
-	}
+    public boolean isIgnoreCapabilities() {
+        return ignoreCapabilities;
+    }
 
-	public void setIgnoreProperties(boolean ignoreProperties) {
-		this.ignoreProperties = ignoreProperties;
-	}
+    public void setIgnoreCapabilities(boolean ignoreCapabilities) {
+        this.ignoreCapabilities = ignoreCapabilities;
+    }
 
-	public boolean isIgnoreCapabilities() {
-		return ignoreCapabilities;
-	}
+    public boolean isIgnoreRequirements() {
+        return ignoreRequirements;
+    }
 
-	public void setIgnoreCapabilities(boolean ignoreCapabilities) {
-		this.ignoreCapabilities = ignoreCapabilities;
-	}
+    public void setIgnoreRequirements(boolean ignoreRequirements) {
+        this.ignoreRequirements = ignoreRequirements;
+    }
 
-	public boolean isIgnoreRequirements() {
-		return ignoreRequirements;
-	}
+    public boolean isIgnoreCategories() {
+        return ignoreCategories;
+    }
 
-	public void setIgnoreRequirements(boolean ignoreRequirements) {
-		this.ignoreRequirements = ignoreRequirements;
-	}
+    public void setIgnoreCategories(boolean ignoreCategories) {
+        this.ignoreCategories = ignoreCategories;
+    }
 
-	public boolean isIgnoreCategories() {
-		return ignoreCategories;
-	}
+    public boolean isIgnoreAllVersions() {
+        return ignoreAllVersions;
+    }
 
-	public void setIgnoreCategories(boolean ignoreCategories) {
-		this.ignoreCategories = ignoreCategories;
-	}
+    public void setIgnoreAllVersions(boolean ignoreAllVersions) {
+        this.ignoreAllVersions = ignoreAllVersions;
+    }
 
-	public boolean isIgnoreAllVersions() {
-		return ignoreAllVersions;
-	}
+    public boolean isIgnoreAdditionalInformation() {
+        return ignoreAdditionalInformation;
+    }
 
-	public void setIgnoreAllVersions(boolean ignoreAllVersions) {
-		this.ignoreAllVersions = ignoreAllVersions;
-	}
+    private void setIgnoreAdditionalInformation(boolean ignoreAdditionalInformation) {
+        this.ignoreAdditionalInformation = ignoreAdditionalInformation;
+    }
 
-	public boolean isIgnoreAdditionalInformation() {
-		return ignoreAdditionalInformation;
-	}
+    public boolean isIgnoreArtifacts() {
+        return ignoreArtifacts;
+    }
 
-	public void setIgnoreAdditionalInformation(boolean ignoreAdditionalInformation) {
-		this.ignoreAdditionalInformation = ignoreAdditionalInformation;
-	}
+    public void setIgnoreArtifacts(boolean ignoreArtifacts) {
+        this.ignoreArtifacts = ignoreArtifacts;
+    }
 
-	public boolean isIgnoreArtifacts() {
-		return ignoreArtifacts;
-	}
+    public boolean isIgnoreComponentInstancesProperties() {
+        return ignoreComponentInstancesProperties;
+    }
 
-	public void setIgnoreArtifacts(boolean ignoreArtifacts) {
-		this.ignoreArtifacts = ignoreArtifacts;
-	}
+    public void setIgnoreComponentInstancesProperties(boolean ignoreComponentInstancesProperties) {
+        this.ignoreComponentInstancesProperties = ignoreComponentInstancesProperties;
+    }
 
-	public boolean isIgnoreComponentInstancesProperties() {
-		return ignoreComponentInstancesProperties;
-	}
+    public boolean isIgnoreComponentInstancesInputs() {
+        return ignoreComponentInstancesInputs;
+    }
 
-	public void setIgnoreComponentInstancesProperties(boolean ignoreComponentInstancesProperties) {
-		this.ignoreComponentInstancesProperties = ignoreComponentInstancesProperties;
-	}
+    public void setIgnoreComponentInstancesInputs(boolean ignoreComponentInstancesInputs) {
+        this.ignoreComponentInstancesInputs = ignoreComponentInstancesInputs;
+    }
 
-	public boolean isIgnoreComponentInstancesInputs() {
-		return ignoreComponentInstancesInputs;
-	}
+    public boolean isIgnoreInterfaces() {
+        return ignoreInterfaces;
+    }
 
-	public void setIgnoreComponentInstancesInputs(boolean ignoreComponentInstancesInputs) {
-		this.ignoreComponentInstancesInputs = ignoreComponentInstancesInputs;
-	}
+    public void setIgnoreInterfaces(boolean ignoreInterfaces) {
+        this.ignoreInterfaces = ignoreInterfaces;
+    }
 
-	public boolean isIgnoreInterfaces() {
-		return ignoreInterfaces;
-	}
+    public boolean isIgnoreAttributesFrom() {
+        return ignoreAttributesFrom;
+    }
 
-	public void setIgnoreInterfaces(boolean ignoreInterfaces) {
-		this.ignoreInterfaces = ignoreInterfaces;
-	}
+    public void setIgnoreAttributesFrom(boolean ignoreAttributesFrom) {
+        this.ignoreAttributesFrom = ignoreAttributesFrom;
+    }
 
-	public boolean isIgnoreAttributesFrom() {
-		return ignoreAttributesFrom;
-	}
+    public boolean isIgnoreComponentInstancesAttributesFrom() {
+        return ignoreComponentInstancesAttributesFrom;
+    }
 
-	public void setIgnoreAttributesFrom(boolean ignoreAttributesFrom) {
-		this.ignoreAttributesFrom = ignoreAttributesFrom;
-	}
+    private void setIgnoreComponentInstancesAttributesFrom(boolean ignoreComponentInstancesAttributesFrom) {
+        this.ignoreComponentInstancesAttributesFrom = ignoreComponentInstancesAttributesFrom;
+    }
 
-	public boolean isIgnoreComponentInstancesAttributesFrom() {
-		return ignoreComponentInstancesAttributesFrom;
-	}
+    public boolean isIgnoreDerivedFrom() {
+        return ignoreDerivedFrom;
+    }
 
-	public void setIgnoreComponentInstancesAttributesFrom(boolean ignoreComponentInstancesAttributesFrom) {
-		this.ignoreComponentInstancesAttributesFrom = ignoreComponentInstancesAttributesFrom;
-	}
+    private void setIgnoreDerivedFrom(boolean ignoreDerivedFrom) {
+        this.ignoreDerivedFrom = ignoreDerivedFrom;
+    }
 
-	public boolean isIgnoreDerivedFrom() {
-		return ignoreDerivedFrom;
-	}
+    public boolean isIgnoreUsers() {
+        return ignoreUsers;
+    }
 
-	public void setIgnoreDerivedFrom(boolean ignoreDerivedFrom) {
-		this.ignoreDerivedFrom = ignoreDerivedFrom;
-	}
+    public void setIgnoreUsers(boolean ignoreUsers) {
+        this.ignoreUsers = ignoreUsers;
+    }
 
-	public boolean isIgnoreUsers() {
-		return ignoreUsers;
-	}
+    public boolean isIgnoreInputs() {
+        return ignoreInputs;
+    }
 
-	public void setIgnoreUsers(boolean ignoreUsers) {
-		this.ignoreUsers = ignoreUsers;
-	}
+    public void setIgnoreInputs(boolean ignoreInputs) {
+        this.ignoreInputs = ignoreInputs;
+    }
 
-	public boolean isIgnoreInputs() {
-		return ignoreInputs;
-	}
+    public boolean isIgnoreCapabiltyProperties() {
+        return ignoreCapabiltyProperties;
+    }
 
-	public void setIgnoreInputs(boolean ignoreInputs) {
-		this.ignoreInputs = ignoreInputs;
-	}
+    public void setIgnoreCapabiltyProperties(boolean ignoreCapabiltyProperties) {
+        this.ignoreCapabiltyProperties = ignoreCapabiltyProperties;
+    }
 
-	public boolean isIgnoreCapabiltyProperties() {
-		return ignoreCapabiltyProperties;
-	}
+    public boolean isIgnoreForwardingPath() {
+        return ignoreServicePath;
+    }
 
-	public void setIgnoreCapabiltyProperties(boolean ignoreCapabiltyProperties) {
-		this.ignoreCapabiltyProperties = ignoreCapabiltyProperties;
-	}
+    public void setIgnoreForwardingPath(boolean ignoreServicePath) {
+        this.ignoreServicePath = ignoreServicePath;
+    }
 
-	public boolean isIgnoreForwardingPath() {
-		return ignoreServicePath;
-	}
+    public boolean isIgnorePolicies() {
+        return ignorePolicies;
+    }
 
-	public void setIgnoreForwardingPath(boolean ignoreServicePath) {
-		this.ignoreServicePath = ignoreServicePath;
-	}
-	
-	public boolean isIgnorePolicies() {
-		return ignorePolicies;
-	}
+    public void setIgnorePolicies(boolean ignorePolicies) {
+        this.ignorePolicies = ignorePolicies;
+    }
 
-	public void setIgnorePolicies(boolean ignorePolicies) {
-		this.ignorePolicies = ignorePolicies;
-	}
-	
-	public JsonParseFlagEnum detectParseFlag() {
-		JsonParseFlagEnum parseFlag;
-		if(isIgnoreComponentInstances()){
-			parseFlag = JsonParseFlagEnum.ParseMetadata;
-		} else {
-			parseFlag = JsonParseFlagEnum.ParseAll;
-		}
-		return parseFlag;
-	}
+    public JsonParseFlagEnum detectParseFlag() {
+        JsonParseFlagEnum parseFlag;
+        if (isIgnoreComponentInstances()) {
+            parseFlag = JsonParseFlagEnum.ParseMetadata;
+        } else {
+            parseFlag = JsonParseFlagEnum.ParseAll;
+        }
+        return parseFlag;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.java
index eef455c..18e4098 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.java
@@ -24,12 +24,12 @@
 
 public class ConsumerDefinition extends ConsumerDataDefinition {
 
-	public ConsumerDefinition() {
-		super();
-	}
+    public ConsumerDefinition() {
+        super();
+    }
 
-	public ConsumerDefinition(ConsumerDataDefinition a) {
-		super(a);
+    public ConsumerDefinition(ConsumerDataDefinition a) {
+        super(a);
 
-	}
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CsarInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CsarInfo.java
deleted file mode 100644
index 9d231a7..0000000
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CsarInfo.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package org.openecomp.sdc.be.model;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.PriorityQueue;
-import java.util.Queue;
-
-import org.yaml.snakeyaml.Yaml;
-
-public class CsarInfo {
-	String vfResourceName;
-	User modifier;
-	String csarUUID;
-	Map<String, byte[]> csar;
-	String mainTemplateContent;
-	Map<String, Object> mappedToscaMainTemplate;
-	Map<String, String> createdNodesToscaResourceNames;
-	Queue<String> cvfcToCreateQueue;
-	boolean isUpdate;
-	Map<String, Resource> createdNodes;
-	
-	@SuppressWarnings("unchecked")
-	public CsarInfo(String vfResourceName, User modifier, String csarUUID, Map<String, byte[]> csar, String mainTemplateContent, boolean isUpdate){
-		this.vfResourceName = vfResourceName;
-		this.modifier = modifier;
-		this.csarUUID = csarUUID;
-		this.csar = csar;
-		this.mainTemplateContent = mainTemplateContent;
-		this.mappedToscaMainTemplate = (Map<String, Object>) new Yaml().load(mainTemplateContent);
-		this.createdNodesToscaResourceNames = new HashMap<>();
-		this.cvfcToCreateQueue = new PriorityQueue<>();
-		this.isUpdate = isUpdate;
-		this.createdNodes  = new HashMap<>(); 
-	}
-
-	public String getVfResourceName() {
-		return vfResourceName;
-	}
-
-	public void setVfResourceName(String vfResourceName) {
-		this.vfResourceName = vfResourceName;
-	}
-
-	public User getModifier() {
-		return modifier;
-	}
-
-	public void setModifier(User modifier) {
-		this.modifier = modifier;
-	}
-
-	public String getCsarUUID() {
-		return csarUUID;
-	}
-
-	public void setCsarUUID(String csarUUID) {
-		this.csarUUID = csarUUID;
-	}
-
-	public Map<String, byte[]> getCsar() {
-		return csar;
-	}
-
-	public void setCsar(Map<String, byte[]> csar) {
-		this.csar = csar;
-	}
-
-	public String getMainTemplateContent() {
-		return mainTemplateContent;
-	}
-
-	public Map<String, Object> getMappedToscaMainTemplate() {
-		return mappedToscaMainTemplate;
-	}
-
-	public Map<String, String> getCreatedNodesToscaResourceNames() {
-		return createdNodesToscaResourceNames;
-	}
-
-	public void setCreatedNodesToscaResourceNames(Map<String, String> createdNodesToscaResourceNames) {
-		this.createdNodesToscaResourceNames = createdNodesToscaResourceNames;
-	}
-
-	public Queue<String> getCvfcToCreateQueue() {
-		return cvfcToCreateQueue;
-	}
-
-	public void setCvfcToCreateQueue(Queue<String> cvfcToCreateQueue) {
-		this.cvfcToCreateQueue = cvfcToCreateQueue;
-	}
-
-	public boolean isUpdate() {
-		return isUpdate;
-	}
-
-	public void setUpdate(boolean isUpdate) {
-		this.isUpdate = isUpdate;
-	}
-
-	public Map<String, Resource> getCreatedNodes() {
-		return createdNodes;
-	}
-
-}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java
index c5f4cf9..44c6b7b 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java
@@ -20,63 +20,63 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
 
+import java.util.List;
+
 public class DataTypeDefinition extends DataTypeDataDefinition {
 
-	private DataTypeDefinition derivedFrom;
+    private DataTypeDefinition derivedFrom;
 
-	private List<PropertyConstraint> constraints;
+    private List<PropertyConstraint> constraints;
 
-	private List<PropertyDefinition> properties;
+    private List<PropertyDefinition> properties;
 
-	public DataTypeDefinition() {
-		super();
-	}
+    public DataTypeDefinition() {
+        super();
+    }
 
-	public DataTypeDefinition(DataTypeDataDefinition p) {
-		super(p);
-	}
+    public DataTypeDefinition(DataTypeDataDefinition p) {
+        super(p);
+    }
 
-	public DataTypeDefinition(DataTypeDefinition pd) {
-		this.setName(pd.getName());
-		this.setDerivedFrom(pd.getDerivedFrom());
-		this.setDerivedFromName(pd.getDerivedFromName());
-		this.setUniqueId(pd.getUniqueId());
-		this.setConstraints(pd.getConstraints());
-		this.setDescription(pd.getDescription());
-	}
+    public DataTypeDefinition(DataTypeDefinition pd) {
+        this.setName(pd.getName());
+        this.setDerivedFrom(pd.getDerivedFrom());
+        this.setDerivedFromName(pd.getDerivedFromName());
+        this.setUniqueId(pd.getUniqueId());
+        this.setConstraints(pd.getConstraints());
+        this.setDescription(pd.getDescription());
+    }
 
-	public List<PropertyConstraint> getConstraints() {
-		return constraints;
-	}
+    public List<PropertyConstraint> getConstraints() {
+        return constraints;
+    }
 
-	public void setConstraints(List<PropertyConstraint> constraints) {
-		this.constraints = constraints;
-	}
+    public void setConstraints(List<PropertyConstraint> constraints) {
+        this.constraints = constraints;
+    }
 
-	public DataTypeDefinition getDerivedFrom() {
-		return derivedFrom;
-	}
+    public DataTypeDefinition getDerivedFrom() {
+        return derivedFrom;
+    }
 
-	public void setDerivedFrom(DataTypeDefinition derivedFrom) {
-		this.derivedFrom = derivedFrom;
-	}
+    public void setDerivedFrom(DataTypeDefinition derivedFrom) {
+        this.derivedFrom = derivedFrom;
+    }
 
-	public List<PropertyDefinition> getProperties() {
-		return properties;
-	}
+    public List<PropertyDefinition> getProperties() {
+        return properties;
+    }
 
-	public void setProperties(List<PropertyDefinition> properties) {
-		this.properties = properties;
-	}
+    public void setProperties(List<PropertyDefinition> properties) {
+        this.properties = properties;
+    }
 
-	@Override
-	public String toString() {
-		return super.toString() + " DataTypeDefinition [derivedFrom=" + derivedFrom + ", constraints=" + constraints
-				+ ", properties=" + properties + "]";
-	}
+    @Override
+    public String toString() {
+        return super.toString() + " DataTypeDefinition [derivedFrom=" + derivedFrom + ", constraints=" + constraints
+                + ", properties=" + properties + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DerivedNodeTypeResolver.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DerivedNodeTypeResolver.java
index 0e30211..5104a17 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DerivedNodeTypeResolver.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DerivedNodeTypeResolver.java
@@ -20,12 +20,11 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 
-import fj.data.Either;
+import java.util.List;
 
 public interface DerivedNodeTypeResolver {
 
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.java
index 139cd70..78b5814 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.java
@@ -21,26 +21,26 @@
 package org.openecomp.sdc.be.model;
 
 public enum DistributionStatusEnum {
-	DISTRIBUTION_NOT_APPROVED("Distribution not approved"), DISTRIBUTION_APPROVED("Distribution approved"), DISTRIBUTED("Distributed"), DISTRIBUTION_REJECTED("Distribution rejected");
+    DISTRIBUTION_NOT_APPROVED("Distribution not approved"), DISTRIBUTION_APPROVED("Distribution approved"), DISTRIBUTED("Distributed"), DISTRIBUTION_REJECTED("Distribution rejected");
 
-	private String value;
+    private String value;
 
-	private DistributionStatusEnum(String value) {
-		this.value = value;
-	}
+    private DistributionStatusEnum(String value) {
+        this.value = value;
+    }
 
-	public String getValue() {
-		return value;
-	}
+    public String getValue() {
+        return value;
+    }
 
-	public static DistributionStatusEnum findState(String state) {
+    public static DistributionStatusEnum findState(String state) {
 
-		for (DistributionStatusEnum distributionStatus : DistributionStatusEnum.values()) {
-			if (distributionStatus.name().equalsIgnoreCase(state) || distributionStatus.getValue().equalsIgnoreCase(state)) {
-				return distributionStatus;
-			}
-		}
-		return null;
-	}
+        for (DistributionStatusEnum distributionStatus : DistributionStatusEnum.values()) {
+            if (distributionStatus.name().equalsIgnoreCase(state) || distributionStatus.getValue().equalsIgnoreCase(state)) {
+                return distributionStatus;
+            }
+        }
+        return null;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.java
index 05f69f3..715ae9c 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.java
@@ -21,34 +21,34 @@
 package org.openecomp.sdc.be.model;
 
 public enum DistributionTransitionEnum {
-	APPROVE("approve"), REJECT("reject");
+    APPROVE("approve"), REJECT("reject");
 
-	String displayName;
+    String displayName;
 
-	private DistributionTransitionEnum(String displayName) {
-		this.displayName = displayName;
-	}
+    private DistributionTransitionEnum(String displayName) {
+        this.displayName = displayName;
+    }
 
-	public String getDisplayName() {
-		return displayName;
-	}
+    public String getDisplayName() {
+        return displayName;
+    }
 
-	public static DistributionTransitionEnum getFromDisplayName(String name) {
+    public static DistributionTransitionEnum getFromDisplayName(String name) {
 
-		for (DistributionTransitionEnum val : DistributionTransitionEnum.values()) {
-			if (name.equalsIgnoreCase(val.getDisplayName())) {
-				return val;
-			}
-		}
-		return null;
-	}
+        for (DistributionTransitionEnum val : DistributionTransitionEnum.values()) {
+            if (name.equalsIgnoreCase(val.getDisplayName())) {
+                return val;
+            }
+        }
+        return null;
+    }
 
-	public static String valuesAsString() {
-		StringBuilder sb = new StringBuilder();
-		for (DistributionTransitionEnum op : DistributionTransitionEnum.values()) {
-			sb.append(op.getDisplayName()).append(" ");
-		}
-		return sb.toString();
-	}
+    public static String valuesAsString() {
+        StringBuilder sb = new StringBuilder();
+        for (DistributionTransitionEnum op : DistributionTransitionEnum.values()) {
+            sb.append(op.getDisplayName()).append(" ");
+        }
+        return sb.toString();
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.java
index 5aa3b85..40cfd50 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.java
@@ -22,23 +22,23 @@
 
 public class FunctionalMenuInfo {
 
-	private String functionalMenu;
+    private String functionalMenu;
 
-	public FunctionalMenuInfo() {
-		super();
-	}
+    public FunctionalMenuInfo() {
+        super();
+    }
 
-	public String getFunctionalMenu() {
-		return functionalMenu;
-	}
+    public String getFunctionalMenu() {
+        return functionalMenu;
+    }
 
-	public void setFunctionalMenu(String functionalMenu) {
-		this.functionalMenu = functionalMenu;
-	}
+    public void setFunctionalMenu(String functionalMenu) {
+        this.functionalMenu = functionalMenu;
+    }
 
-	@Override
-	public String toString() {
-		return "FunctionalMenuInfo [functionalMenu=" + functionalMenu + "]";
-	}
+    @Override
+    public String toString() {
+        return "FunctionalMenuInfo [functionalMenu=" + functionalMenu + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.java
index 625afe4..bda5a64 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.java
@@ -20,72 +20,110 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.List;
-import java.util.stream.Collectors;
-
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertiesOwner;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 
-public class GroupDefinition extends GroupDataDefinition implements Serializable {
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -852613634651112247L;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 
-	// properties (properties should be defined in the group type, the
-	// properties here are actually the value for the properties)
+import static java.util.stream.Collectors.*;
+
+public class GroupDefinition extends GroupDataDefinition implements PropertiesOwner{
+
+	private Map<String, List<CapabilityDefinition>> capabilities;
 	
+    public GroupDefinition() {
+        super();
+    }
 
+    public GroupDefinition(GroupDataDefinition other) {
+        super(other);
+    }
 
-
-	// The unique id of the type of this group
-
-
-	public GroupDefinition() {
-		super();
-	}
-
-	public GroupDefinition(GroupDataDefinition other) {
-		super(other);
-	}
-
-	public GroupDefinition(GroupDefinition other) {
-		this.setName(other.getName());
-		this.setUniqueId(other.getUniqueId());
-		this.setType(other.getType());
-		this.setVersion(other.getVersion());
-		this.setInvariantUUID(other.getInvariantUUID());
-		this.setGroupUUID(other.getGroupUUID());
-		this.setDescription(other.getDescription());
-		this.setTypeUid(other.getTypeUid());
-		this.setProperties(other.getProperties());
-		
-	}
-
-	public List<GroupProperty> convertToGroupProperties() {
-		List<GroupProperty> properties = null;
-		List<PropertyDataDefinition> propList = super.getProperties();
-		if(propList != null && !propList .isEmpty()){
-			 properties = propList.stream().map(pr -> new GroupProperty(pr)).collect(Collectors.toList());
+    public GroupDefinition(GroupDefinition other) {
+    	super(other);
+		if(MapUtils.isNotEmpty(other.getCapabilities())) {
+			this.setCapabilities(other.getCapabilities().entrySet()
+					.stream()
+					.collect(toMap(Map.Entry::getKey, e -> getCapabilitiesCopyList(e.getValue()))));
 		}
-		return properties;
 	}
 
-	public void convertFromGroupProperties(List<GroupProperty> properties) {
-		if(properties != null && !properties .isEmpty()){
-			List<PropertyDataDefinition> propList = properties.stream().map(pr -> new PropertyDataDefinition(pr)).collect(Collectors.toList());
-			super.setProperties(propList);
+	public Map<String, List<CapabilityDefinition>> getCapabilities() {
+		if(MapUtils.isEmpty(capabilities)) {
+			capabilities = Maps.newHashMap();
 		}
-		
+		return capabilities;
 	}
 
-	//returns true iff groupName has the same prefix has the resource
-	public boolean isSamePrefix(String resourceName){
-		String name = this.getName();
-		if ( name != null  && name.toLowerCase().trim().startsWith(resourceName.toLowerCase()))
-			return true;
-		return false;
+	public void setCapabilities(Map<String, List<CapabilityDefinition>> capabilities) {
+		this.capabilities = capabilities;
+    }
+
+    public List<GroupProperty> convertToGroupProperties() {
+        List<GroupProperty> properties = null;
+        List<PropertyDataDefinition> propList = super.getProperties();
+        if(propList != null && !propList .isEmpty()){
+			 properties = propList.stream().map(GroupProperty::new).collect(toList());
+        }
+        return properties;
+    }
+
+    public <T extends PropertyDataDefinition> void convertFromGroupProperties(List<T> properties) {
+        if(properties != null && !properties .isEmpty()){
+			List<PropertyDataDefinition> propList = properties.stream().map(PropertyDataDefinition::new).collect(toList());
+            super.setProperties(propList);
+        }
+	}
+	
+    //returns true iff groupName has the same prefix has the resource
+    public boolean isSamePrefix(String resourceName){
+        return getName() != null  && getName().toLowerCase().trim().startsWith(resourceName.toLowerCase());
+    }
+
+    public void convertCapabilityDefinitions(Map<String, CapabilityDefinition> capabilities) {
+        if(MapUtils.isNotEmpty(capabilities)){
+            this.capabilities = capabilities.values().stream()
+                                                      .collect(groupingBy(CapabilityDefinition::getType));
+        }
+    }
+
+	@Override
+	public String getNormalizedName() {
+		return getName();
+	}
+
+	@JsonIgnore
+	private List<CapabilityDefinition> getCapabilitiesCopyList(List<CapabilityDefinition> capabilities) {
+		return Lists.newArrayList(capabilities.stream().map(CapabilityDefinition::new).collect(toList()));
+	}
+
+	public void updateCapabilitiesProperties(Map<String, Map<String, CapabilityDefinition>> capabilitiesInfo) {
+		if(MapUtils.isNotEmpty(capabilities) && MapUtils.isNotEmpty(capabilitiesInfo)){
+			capabilities.entrySet().forEach(e->updateCapabilitiesProperies(e.getValue(), capabilitiesInfo.get(e.getKey())));
+		}
+	}
+
+	private void updateCapabilitiesProperies(List<CapabilityDefinition> capabilities, Map<String, CapabilityDefinition> capabilitiesInfo) {
+		if(CollectionUtils.isNotEmpty(capabilities) && MapUtils.isNotEmpty(capabilitiesInfo)){
+			capabilities.forEach(c->c.updateCapabilityProperties(capabilitiesInfo.get(c.getName())));
+		}
+	}
+
+	public void updateEmptyCapabilitiesOwnerFields(){
+    	if(MapUtils.isNotEmpty(this.capabilities)){
+    		this.capabilities.values().stream()
+					.flatMap(Collection::stream)
+					.forEach(c -> c.updateEmptyCapabilityOwnerFields(getUniqueId(), getName(), CapabilityDataDefinition.OwnerType.GROUP));
+		}
 	}
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupInstance.java
index e9efa8f..dbf520e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupInstance.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupInstance.java
@@ -20,66 +20,59 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
 
-public class GroupInstance extends GroupInstanceDataDefinition implements Serializable {
+import java.util.*;
+import java.util.stream.Collectors;
 
-	private static final long serialVersionUID = -2066335818115254401L;
-	
-	public GroupInstance() {
-		super();
-	}
-	
-	public GroupInstance(GroupInstanceDataDefinition r) {
-		super(r);
-	}
-	/**
-	 * Converts contained list of PropertyDataDefinitions to list of GroupInstanceProperties
-	 * @return
-	 */
-	public List<GroupInstanceProperty>  convertToGroupInstancesProperties() {
-		List<GroupInstanceProperty> groupInstancesProperties = null;
-		List<PropertyDataDefinition> propertiesList = super.getProperties();
-		if(propertiesList != null && !propertiesList .isEmpty()){
-			groupInstancesProperties = propertiesList.stream().map(p -> new GroupInstanceProperty(p)).collect(Collectors.toList());
-		}
-		return groupInstancesProperties;
-	}
-	/**
-	 * Converts received list of GroupInstanceProperties to the list of PropertyDataDefinitions and sets It into the GroupInstanceDataDefinition as properties
-	 * @param groupInstancesProperties
-	 */
-	public void convertFromGroupInstancesProperties(List<GroupInstanceProperty> groupInstancesProperties) {
-		if(groupInstancesProperties != null && !groupInstancesProperties .isEmpty()){
-			List<PropertyDataDefinition> propList = groupInstancesProperties.stream().map(p -> new PropertyDataDefinition(p)).collect(Collectors.toList());
-			super.setProperties(propList);
-		}
-	}
-	
-	private void removeArtifactsDuplicates() {
-		List<String> artifacts = getArtifacts();
-		Set<String> artifactsSet = new HashSet<>();
+public class GroupInstance extends GroupInstanceDataDefinition {
+
+    public GroupInstance() {
+        super();
+    }
+
+    public GroupInstance(GroupInstanceDataDefinition r) {
+        super(r);
+    }
+    /**
+     * Converts contained list of PropertyDataDefinitions to list of GroupInstanceProperties
+     * @return
+     */
+    public List<GroupInstanceProperty>  convertToGroupInstancesProperties() {
+        List<GroupInstanceProperty> groupInstancesProperties = null;
+        List<PropertyDataDefinition> propertiesList = super.getProperties();
+        if(propertiesList != null && !propertiesList .isEmpty()){
+            groupInstancesProperties = propertiesList.stream().map(GroupInstanceProperty::new).collect(Collectors.toList());
+        }
+        return groupInstancesProperties;
+    }
+    /**
+     * Converts received list of GroupInstanceProperties to the list of PropertyDataDefinitions and sets It into the GroupInstanceDataDefinition as properties
+     * @param groupInstancesProperties
+     */
+    public void convertFromGroupInstancesProperties(List<GroupInstanceProperty> groupInstancesProperties) {
+        if(groupInstancesProperties != null && !groupInstancesProperties .isEmpty()){
+            List<PropertyDataDefinition> propList = groupInstancesProperties.stream().map(PropertyDataDefinition::new).collect(Collectors.toList());
+            super.setProperties(propList);
+        }
+    }
+
+    private void removeArtifactsDuplicates() {
+        List<String> artifacts = getArtifacts();
+        Set<String> artifactsSet = new HashSet<>();
 		
 		if (artifacts != null && !artifacts.isEmpty()) {
 			artifactsSet.addAll(artifacts);
 			artifacts.clear();
 			artifacts.addAll(artifactsSet);
 		}
-		
-		List<String> giArtifacts = getGroupInstanceArtifacts();
-		Set<String> giArtifactsSet = new HashSet<>();
+
+        List<String> giArtifacts = getGroupInstanceArtifacts();
+        Set<String> giArtifactsSet = new HashSet<>();
 		
 		if (giArtifacts != null && !giArtifacts.isEmpty()) {
 			giArtifactsSet.addAll(giArtifacts);
@@ -88,52 +81,52 @@
 		}
 	}
 
-	private void clearArtifactsUuid() {
-		List<String> artifactsUuid = getArtifactsUuid();
-		if(CollectionUtils.isNotEmpty(artifactsUuid)){
-			artifactsUuid.clear();
-		} else if (artifactsUuid == null){
-			setArtifactsUuid(new ArrayList<>());
-		}
-		
-		List<String> giartifactsUuid = this.getGroupInstanceArtifactsUuid();
-		if(CollectionUtils.isNotEmpty(giartifactsUuid)){
-			giartifactsUuid.clear();
-		} else if (giartifactsUuid == null){
-			setGroupInstanceArtifactsUuid(new ArrayList<>());
-		}
-	}
-	
-	/**
-	 * Aligns the list of artifacts UUIDs of group instance according to received deployment artifacts
-	 * @param deploymentArtifacts
-	 */
-	public void alignArtifactsUuid(Map<String, ArtifactDefinition> deploymentArtifacts) {
-		List<String> artifactIds = getArtifacts();
-		if(CollectionUtils.isNotEmpty(artifactIds) && deploymentArtifacts != null){
-			removeArtifactsDuplicates();
-			clearArtifactsUuid();
-			List<String> artifactUuids = getArtifactsUuid();
-			List<String> giArtifactUuids = getGroupInstanceArtifactsUuid();
-			for(String artifactId : artifactIds){
-				String label = artifactId.substring(artifactId.lastIndexOf('.') + 1);
-				ArtifactDefinition artifact = deploymentArtifacts.get(label);
-				ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifact.getArtifactType());
-				if (artifactType != ArtifactTypeEnum.HEAT_ENV){
-					addArtifactsIdToCollection(artifactUuids, artifact);
-				}else{
-					addArtifactsIdToCollection(giArtifactUuids, artifact);
-				}
-			}
-			
-		}
-	}
+    private void clearArtifactsUuid() {
+        List<String> artifactsUuid = getArtifactsUuid();
+        if(CollectionUtils.isNotEmpty(artifactsUuid)){
+            artifactsUuid.clear();
+        } else if (artifactsUuid == null){
+            setArtifactsUuid(new ArrayList<>());
+        }
 
-	private void addArtifactsIdToCollection(List<String> artifactUuids, ArtifactDefinition artifact) {
-		if(!artifactUuids.contains(artifact.getArtifactUUID()) && StringUtils.isNotEmpty(artifact.getArtifactUUID())){
-			artifactUuids.add(artifact.getArtifactUUID());
-		
-		}
-	}
+        List<String> giartifactsUuid = this.getGroupInstanceArtifactsUuid();
+        if(CollectionUtils.isNotEmpty(giartifactsUuid)){
+            giartifactsUuid.clear();
+        } else if (giartifactsUuid == null){
+            setGroupInstanceArtifactsUuid(new ArrayList<>());
+        }
+    }
+
+    /**
+     * Aligns the list of artifacts UUIDs of group instance according to received deployment artifacts
+     * @param deploymentArtifacts
+     */
+    public void alignArtifactsUuid(Map<String, ArtifactDefinition> deploymentArtifacts) {
+        List<String> artifactIds = getArtifacts();
+	if(CollectionUtils.isNotEmpty(artifactIds) && deploymentArtifacts != null){
+            removeArtifactsDuplicates();
+            clearArtifactsUuid();
+            List<String> artifactUuids = getArtifactsUuid();
+            List<String> giArtifactUuids = getGroupInstanceArtifactsUuid();
+            for(String artifactId : artifactIds){
+                String label = artifactId.substring(artifactId.lastIndexOf('.') + 1);
+                ArtifactDefinition artifact = deploymentArtifacts.get(label);
+                ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifact.getArtifactType());
+                if (artifactType != ArtifactTypeEnum.HEAT_ENV){
+                    addArtifactsIdToCollection(artifactUuids, artifact);
+                }else{
+                    addArtifactsIdToCollection(giArtifactUuids, artifact);
+                }
+            }
+
+        }
+    }
+
+    private void addArtifactsIdToCollection(List<String> artifactUuids, ArtifactDefinition artifact) {
+        if(!artifactUuids.contains(artifact.getArtifactUUID()) && StringUtils.isNotEmpty(artifact.getArtifactUUID())){
+            artifactUuids.add(artifact.getArtifactUUID());
+
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupInstanceProperty.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupInstanceProperty.java
index 683a2f2..55b3345 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupInstanceProperty.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupInstanceProperty.java
@@ -23,41 +23,37 @@
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 
 public class GroupInstanceProperty extends GroupProperty {
-	
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 1L;
-	private String parentValue;
-	
-	public GroupInstanceProperty() {
-		super();
-	}
 
-	public GroupInstanceProperty(GroupProperty gp, String parentValue) {
-		super(gp);
-		this.parentValue = parentValue;
-	}
+    private String parentValue;
 
-	public GroupInstanceProperty(GroupInstanceProperty other) {
-		super(other);
-		if (other != null) {
-			this.parentValue = other.getParentValue();
-		}
-	}
-	
-	public GroupInstanceProperty(PropertyDataDefinition propertyDataDefinition) {
-		super(propertyDataDefinition);
-		parentValue = getDefaultValue();
-	}
+    public GroupInstanceProperty() {
+        super();
+    }
 
-	public String getParentValue() {
-		return parentValue;
-	}
+    public GroupInstanceProperty(GroupProperty gp, String parentValue) {
+        super(gp);
+        this.parentValue = parentValue;
+    }
 
-	public void setParentValue(String parentValue) {
-		this.parentValue = parentValue;
-	}
-	
-	
+    public GroupInstanceProperty(GroupInstanceProperty other) {
+        super(other);
+        if (other != null) {
+            this.parentValue = other.getParentValue();
+        }
+    }
+
+    public GroupInstanceProperty(PropertyDataDefinition propertyDataDefinition) {
+        super(propertyDataDefinition);
+        parentValue = getDefaultValue();
+    }
+
+    public String getParentValue() {
+        return parentValue;
+    }
+
+    public void setParentValue(String parentValue) {
+        this.parentValue = parentValue;
+    }
+
+
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.java
index 649aa1f..95702a3 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.java
@@ -24,50 +24,45 @@
 
 public class GroupProperty extends PropertyDefinition {
 
-	/**
-	 * current value
-	 */
-//	private String value;
+    /**
+     * The unique is of Group property on graph. If it is null, then the
+     * property's value was not updated. The value is taken from the group type
+     * property.
+     */
+    private String valueUniqueUid;
 
-	/**
-	 * The unique is of Group property on graph. If it is null, then the
-	 * property's value was not updated. The value is taken from the group type
-	 * property.
-	 */
-	private String valueUniqueUid;
+    public GroupProperty() {
+        super();
+    }
 
-	public GroupProperty() {
-		super();
-	}
+    public GroupProperty(PropertyDefinition pd, String value, String valueUniqueUid) {
+        super(pd);
+        setValue(value);
+        this.valueUniqueUid = valueUniqueUid;
+    }
 
-	public GroupProperty(PropertyDefinition pd, String value, String valueUniqueUid) {
-		super(pd);
-		setValue(value);
-		this.valueUniqueUid = valueUniqueUid;
-	}
+    public GroupProperty(GroupProperty other) {
+        super(other);
+        if (other != null) {
+            setValue(other.getValue());
+            this.valueUniqueUid = other.getValueUniqueUid();
+        }
+    }
+    public GroupProperty(PropertyDataDefinition other) {
+        super(other);
+    }
 
-	public GroupProperty(GroupProperty other) {
-		super(other);
-		if (other != null) {
-			setValue(other.getValue());
-			this.valueUniqueUid = other.getValueUniqueUid();
-		}
-	}
-	public GroupProperty(PropertyDataDefinition other) {
-		super(other);
-	}
+    public String getValueUniqueUid() {
+        return valueUniqueUid;
+    }
 
-	public String getValueUniqueUid() {
-		return valueUniqueUid;
-	}
+    public void setValueUniqueUid(String valueUniqueUid) {
+        this.valueUniqueUid = valueUniqueUid;
+    }
 
-	public void setValueUniqueUid(String valueUniqueUid) {
-		this.valueUniqueUid = valueUniqueUid;
-	}
-
-	@Override
-	public String toString() {
-		return "GroupProperty [ " + super.toString() + ", valueUniqueUid = " + valueUniqueUid
-				+ " ]";
-	}
+    @Override
+    public String toString() {
+        return "GroupProperty [ " + super.toString() + ", valueUniqueUid = " + valueUniqueUid
+                + " ]";
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.java
index 5263fcf..ec1c334 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.java
@@ -20,51 +20,46 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.elements.GroupTypeDataDefinition;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * Specifies the group type that the Node Type exposes.
  */
-public class GroupTypeDefinition extends GroupTypeDataDefinition implements Serializable {
+public class GroupTypeDefinition extends GroupTypeDataDefinition {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -1597773317924162703L;
+    private List<PropertyDefinition> properties;
+	private Map<String, CapabilityDefinition> capabilities;
 
-	private List<PropertyDefinition> properties;
-	private List<CapabilityTypeDefinition> capabilityTypes;
+    public List<PropertyDefinition> getProperties() {
+        return properties;
+    }
 
-	public List<PropertyDefinition> getProperties() {
-		return properties;
-	}
+    public void setProperties(List<PropertyDefinition> properties) {
+        this.properties = properties;
+    }
 
-	public void setProperties(List<PropertyDefinition> properties) {
-		this.properties = properties;
-	}
+    public GroupTypeDefinition() {
+        super();
+    }
 
-	public GroupTypeDefinition() {
-		super();
-	}
+    public GroupTypeDefinition(GroupTypeDataDefinition p) {
+        super(p);
+    }
 
-	public GroupTypeDefinition(GroupTypeDataDefinition p) {
-		super(p);
-	}
+	public Map<String, CapabilityDefinition> getCapabilities() {
+        return capabilities;
+    }
 
-	public List<CapabilityTypeDefinition> getCapabilityTypes() {
-		return capabilityTypes;
-	}
-	
-	public void setCapabilityTypes(List<CapabilityTypeDefinition> capabilityTypes) {
-		this.capabilityTypes = capabilityTypes;
-	}
+	public void setCapabilities(Map<String, CapabilityDefinition> capabilies) {
+        this.capabilities = capabilies;
+    }
 
-	@Override
-	public String toString() {
-		return super.toString() + " [properties=" + properties + ", capabilityTypes=" + capabilityTypes + "]";
-	}
+    @Override
+    public String toString() {
+        return super.toString() + " [properties=" + properties + ", capabilities=" + capabilities + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.java
index 8e03361..3f5c7b6 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.java
@@ -20,23 +20,15 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-
 import org.openecomp.sdc.be.datatypes.elements.HeatParameterDataDefinition;
 
-public class HeatParameterDefinition extends HeatParameterDataDefinition implements Serializable {
+public class HeatParameterDefinition extends HeatParameterDataDefinition {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 3400360721469962105L;
+    public HeatParameterDefinition(HeatParameterDataDefinition hpdd) {
+        super(hpdd);
+    }
 
-	public HeatParameterDefinition(HeatParameterDataDefinition hpdd) {
-		super(hpdd);
-	}
-
-	public HeatParameterDefinition() {
-		super();
-	}
-
+    public HeatParameterDefinition() {
+        super();
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.java
index 3d21e07..bc3fe50 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.java
@@ -23,13 +23,13 @@
 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 
 public interface IComplexDefaultValue {
-	String getType();
+    String getType();
 
-	String getName();
+    String getName();
 
-	String getDefaultValue();
+    String getDefaultValue();
 
-	void setDefaultValue(String value);
+    void setDefaultValue(String value);
 
-	SchemaDefinition getSchema();
+    SchemaDefinition getSchema();
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.java
index 80e8986..3de05c3 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.java
@@ -21,14 +21,14 @@
 package org.openecomp.sdc.be.model;
 
 public interface IComponentInstanceConnectedElement {
-	String getUniqueId();
+    String getUniqueId();
 
-	String getValueUniqueUid();
+    String getValueUniqueUid();
 
-	void setValueUniqueUid(String value);
-	
-	String getComponentInstanceName();
-	void setComponentInstanceName(String componentInstanceName);
-	String getComponentInstanceId();
-	void setComponentInstanceId(String componentInstanceId);
+    void setValueUniqueUid(String value);
+
+    String getComponentInstanceName();
+    void setComponentInstanceName(String componentInstanceName);
+    String getComponentInstanceId();
+    void setComponentInstanceId(String componentInstanceId);
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.java
index 1419353..6fbad20 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.java
@@ -25,13 +25,13 @@
  * a PropertyDefinition.
  */
 public interface IOperationParameter {
-	/**
-	 * Allow to know if the operation parameter is a property definition or a
-	 * property value. Only parameter exposed as property definitions can be
-	 * used for "custom" operations.
-	 *
-	 * @return true if the operation parameter is a property definition and
-	 *         false if the parameter is a property value.
-	 */
-	boolean isDefinition();
+    /**
+     * Allow to know if the operation parameter is a property definition or a
+     * property value. Only parameter exposed as property definitions can be
+     * used for "custom" operations.
+     *
+     * @return true if the operation parameter is a property definition and
+     *         false if the parameter is a property value.
+     */
+    boolean isDefinition();
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IPropertyInputCommon.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IPropertyInputCommon.java
index 2f7a580..80b6993 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IPropertyInputCommon.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IPropertyInputCommon.java
@@ -1,14 +1,14 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 
+import java.util.List;
+
 public interface IPropertyInputCommon {
 
-	String getType();
-	SchemaDefinition getSchema();
-	List<PropertyRule> getRules();
-	String getName();
+    String getType();
+    SchemaDefinition getSchema();
+    List<PropertyRule> getRules();
+    String getName();
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java
index afd555e..77bc916 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java
@@ -20,8 +20,6 @@
 
 package org.openecomp.sdc.be.model;
 
-import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
-
 /**
  * Specifies an implementation artifact for interfaces or operations of a
  * {@link NodeType node type} or {@link RelationshipType relation type}.
@@ -29,41 +27,41 @@
  * @author esofer
  */
 public class ImplementationArtifact {
-	/**
-	 * <p>
-	 * Specifies the type of this artifact.
-	 * </p>
-	 */
-	private String artifactType;
+    /**
+     * <p>
+     * Specifies the type of this artifact.
+     * </p>
+     */
+    private String artifactType;
 
-	/**
-	 * <p>
-	 * Identifies an Artifact Template to be used as implementation artifact.
-	 * This Artifact Template can be defined in the same Definitions document or
-	 * in a separate, imported document.
-	 * </p>
-	 * 
-	 * <p>
-	 * The type of Artifact Template referenced by the artifactRef attribute
-	 * MUST be the same type or a sub-type of the type specified in the
-	 * artifactType attribute.
-	 * </p>
-	 * 
-	 * <p>
-	 * Note: if no Artifact Template is referenced, the artifact type specific
-	 * content of the ImplementationArtifact element alone is assumed to
-	 * represent the actual artifact. For example, a simple script could be
-	 * defined in place within the ImplementationArtifact element.
-	 * </p>
-	 */
-	private String artifactRef;
+    /**
+     * <p>
+     * Identifies an Artifact Template to be used as implementation artifact.
+     * This Artifact Template can be defined in the same Definitions document or
+     * in a separate, imported document.
+     * </p>
+     *
+     * <p>
+     * The type of Artifact Template referenced by the artifactRef attribute
+     * MUST be the same type or a sub-type of the type specified in the
+     * artifactType attribute.
+     * </p>
+     *
+     * <p>
+     * Note: if no Artifact Template is referenced, the artifact type specific
+     * content of the ImplementationArtifact element alone is assumed to
+     * represent the actual artifact. For example, a simple script could be
+     * defined in place within the ImplementationArtifact element.
+     * </p>
+     */
+    private String artifactRef;
 
-	/**
-	 * The name of the archive in which the artifact lies.
-	 */
-	private String archiveName;
-	/**
-	 * The version of the archive in which the artifact lies.
-	 */
-	private String archiveVersion;
+    /**
+     * The name of the archive in which the artifact lies.
+     */
+    private String archiveName;
+    /**
+     * The version of the archive in which the artifact lies.
+     */
+    private String archiveVersion;
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java
index 2359d63..2f61e9e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java
@@ -20,46 +20,55 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
+import org.openecomp.sdc.be.datatypes.elements.Annotation;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
 public class InputDefinition extends PropertyDefinition {
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -6920076037265309468L;
 
-	List<ComponentInstanceInput> inputs;
-	List<ComponentInstanceProperty> properties;
+    private List<ComponentInstanceInput> inputs;
+    private List<ComponentInstanceProperty> properties;
 
-	public InputDefinition() {
-		super();
-	}
 
-	public InputDefinition(PropertyDataDefinition p) {
-		super(p);
-	}
+    public InputDefinition(PropertyDataDefinition p) {
+        super(p);
+    }
 
-	public InputDefinition(PropertyDefinition pd) {
-		super(pd);
-	}
+    public InputDefinition() {
+        super();
+    }
 
-	
-	public List<ComponentInstanceInput> getInputs() {
-		return inputs;
-	}
+    public InputDefinition(PropertyDefinition pd) {
+        super(pd);
+    }
 
-	public void setInputs(List<ComponentInstanceInput> inputs) {
-		this.inputs = inputs;
-	}
+    public InputDefinition(InputDefinition other) {
+        super(other);
+    }
 
-	public List<ComponentInstanceProperty> getProperties() {
-		return properties;
-	}
+    public List<ComponentInstanceInput> getInputs() {
+        return inputs;
+    }
 
-	public void setProperties(List<ComponentInstanceProperty> properties) {
-		this.properties = properties;
-	}
+    public void setInputs(List<ComponentInstanceInput> inputs) {
+        this.inputs = inputs;
+    }
+
+    public List<ComponentInstanceProperty> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<ComponentInstanceProperty> properties) {
+        this.properties = properties;
+    }
+
+    public void setAnnotationsToInput(Collection<Annotation> annotations){
+        this.setAnnotations(new ArrayList<>(annotations));
+    }
+
+
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.java
index e1a648c..3afd422 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.java
@@ -20,14 +20,12 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.Map;
-import java.util.stream.Collectors;
-
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * Definition of the operations that can be performed on (instances of) a Node
@@ -35,13 +33,7 @@
  *
  * @author esofer
  */
-public class InterfaceDefinition extends InterfaceDataDefinition implements IOperationParameter, Serializable {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 8220887972866354746L;
-
+public class InterfaceDefinition extends InterfaceDataDefinition implements IOperationParameter {
 
     private boolean definition;
 
@@ -69,19 +61,18 @@
 
     @JsonIgnore
     public Map<String, Operation> getOperationsMap() {
-        Map<String, Operation> convertedOperation = getOperations().entrySet()
-            .stream()
-            .collect(Collectors.toMap(e -> e.getKey(), e -> new Operation(e
-                .getValue())));
-        return convertedOperation;
+        return getOperations().entrySet()
+                              .stream()
+                              .collect(Collectors.toMap(Map.Entry::getKey, e -> new Operation(e
+                                                                           .getValue())));
     }
 
     @JsonIgnore
     public void setOperationsMap(Map<String, Operation> operations) {
         Map<String, OperationDataDefinition> convertedOperation = operations.entrySet()
-            .stream()
-            .collect(Collectors.toMap(e -> e.getKey(), e -> new OperationDataDefinition(e
-                .getValue())));
+                                                                            .stream()
+                                                                            .collect(Collectors.toMap(Map.Entry::getKey, e -> new OperationDataDefinition(e
+                                                                                    .getValue())));
         setOperations(convertedOperation);
     }
 
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.java
index 7d135c5..8aee955 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.java
@@ -22,62 +22,62 @@
 
 public enum LifeCycleTransitionEnum {
 
-	CHECKOUT("checkout"), 
-	CHECKIN("checkin"), 
-	CERTIFICATION_REQUEST("certificationRequest"), 
-	UNDO_CHECKOUT("undoCheckout"), 
-	CANCEL_CERTIFICATION("cancelCertification"), 
-	START_CERTIFICATION("startCertification"), 
-	FAIL_CERTIFICATION("failCertification"), 
-	CERTIFY("certify"), 
-	DISTRIBUTE("distribute");
+    CHECKOUT("checkout"),
+    CHECKIN("checkin"),
+    CERTIFICATION_REQUEST("certificationRequest"),
+    UNDO_CHECKOUT("undoCheckout"),
+    CANCEL_CERTIFICATION("cancelCertification"),
+    START_CERTIFICATION("startCertification"),
+    FAIL_CERTIFICATION("failCertification"),
+    CERTIFY("certify"),
+    DISTRIBUTE("distribute");
 
-	String displayName;
+    String displayName;
 
-	private LifeCycleTransitionEnum(String displayName) {
-		this.displayName = displayName;
-	}
+    private LifeCycleTransitionEnum(String displayName) {
+        this.displayName = displayName;
+    }
 
-	public String getDisplayName() {
-		return displayName;
-	}
+    public String getDisplayName() {
+        return displayName;
+    }
 
-	public static LifeCycleTransitionEnum getFromDisplayName(String name) {
-		if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CHECKOUT.getDisplayName())) {
-			return LifeCycleTransitionEnum.CHECKOUT;
-		}
-		if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CHECKIN.getDisplayName())) {
-			return LifeCycleTransitionEnum.CHECKIN;
-		}
-		if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CERTIFICATION_REQUEST.getDisplayName())) {
-			return LifeCycleTransitionEnum.CERTIFICATION_REQUEST;
-		}
-		if (name.equalsIgnoreCase(LifeCycleTransitionEnum.UNDO_CHECKOUT.getDisplayName())) {
-			return LifeCycleTransitionEnum.UNDO_CHECKOUT;
-		}
-		if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CANCEL_CERTIFICATION.getDisplayName())) {
-			return LifeCycleTransitionEnum.CANCEL_CERTIFICATION;
-		}
-		if (name.equalsIgnoreCase(LifeCycleTransitionEnum.START_CERTIFICATION.getDisplayName())) {
-			return LifeCycleTransitionEnum.START_CERTIFICATION;
-		}
-		if (name.equalsIgnoreCase(LifeCycleTransitionEnum.FAIL_CERTIFICATION.getDisplayName())) {
-			return LifeCycleTransitionEnum.FAIL_CERTIFICATION;
-		}
-		if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CERTIFY.getDisplayName())) {
-			return LifeCycleTransitionEnum.CERTIFY;
-		}
-		if (name.equalsIgnoreCase(LifeCycleTransitionEnum.DISTRIBUTE.getDisplayName())) {
-			return LifeCycleTransitionEnum.DISTRIBUTE;
-		} else
-			throw new IllegalArgumentException(name + " value does not match any of LifeCycleTransitionEnum values");
-	}
+    public static LifeCycleTransitionEnum getFromDisplayName(String name) {
+        if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CHECKOUT.getDisplayName())) {
+            return LifeCycleTransitionEnum.CHECKOUT;
+        }
+        if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CHECKIN.getDisplayName())) {
+            return LifeCycleTransitionEnum.CHECKIN;
+        }
+        if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CERTIFICATION_REQUEST.getDisplayName())) {
+            return LifeCycleTransitionEnum.CERTIFICATION_REQUEST;
+        }
+        if (name.equalsIgnoreCase(LifeCycleTransitionEnum.UNDO_CHECKOUT.getDisplayName())) {
+            return LifeCycleTransitionEnum.UNDO_CHECKOUT;
+        }
+        if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CANCEL_CERTIFICATION.getDisplayName())) {
+            return LifeCycleTransitionEnum.CANCEL_CERTIFICATION;
+        }
+        if (name.equalsIgnoreCase(LifeCycleTransitionEnum.START_CERTIFICATION.getDisplayName())) {
+            return LifeCycleTransitionEnum.START_CERTIFICATION;
+        }
+        if (name.equalsIgnoreCase(LifeCycleTransitionEnum.FAIL_CERTIFICATION.getDisplayName())) {
+            return LifeCycleTransitionEnum.FAIL_CERTIFICATION;
+        }
+        if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CERTIFY.getDisplayName())) {
+            return LifeCycleTransitionEnum.CERTIFY;
+        }
+        if (name.equalsIgnoreCase(LifeCycleTransitionEnum.DISTRIBUTE.getDisplayName())) {
+            return LifeCycleTransitionEnum.DISTRIBUTE;
+        } else
+            throw new IllegalArgumentException(name + " value does not match any of LifeCycleTransitionEnum values");
+    }
 
-	public static String valuesAsString() {
-		StringBuilder sb = new StringBuilder();
-		for (LifeCycleTransitionEnum op : LifeCycleTransitionEnum.values()) {
-			sb.append(op.getDisplayName()).append(" ");
-		}
-		return sb.toString();
-	}
+    public static String valuesAsString() {
+        StringBuilder sb = new StringBuilder();
+        for (LifeCycleTransitionEnum op : LifeCycleTransitionEnum.values()) {
+            sb.append(op.getDisplayName()).append(" ");
+        }
+        return sb.toString();
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.java
index 4d9ef81..57ceb90 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.java
@@ -22,23 +22,23 @@
 
 public enum LifecycleStateEnum {
 
-	READY_FOR_CERTIFICATION,
+    READY_FOR_CERTIFICATION,
 
-	CERTIFICATION_IN_PROGRESS,
+    CERTIFICATION_IN_PROGRESS,
 
-	CERTIFIED,
+    CERTIFIED,
 
-	NOT_CERTIFIED_CHECKIN,
+    NOT_CERTIFIED_CHECKIN,
 
-	NOT_CERTIFIED_CHECKOUT;
+    NOT_CERTIFIED_CHECKOUT;
 
-	public static LifecycleStateEnum findState(String state) {
+    public static LifecycleStateEnum findState(String state) {
 
-		for (LifecycleStateEnum lifecycleStateEnum : LifecycleStateEnum.values()) {
-			if (lifecycleStateEnum.name().equals(state)) {
-				return lifecycleStateEnum;
-			}
-		}
-		return null;
-	}
+        for (LifecycleStateEnum lifecycleStateEnum : LifecycleStateEnum.values()) {
+            if (lifecycleStateEnum.name().equals(state)) {
+                return lifecycleStateEnum;
+            }
+        }
+        return null;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/NodeTypeInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/NodeTypeInfo.java
index 1da3b8d..0dbbc94 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/NodeTypeInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/NodeTypeInfo.java
@@ -4,52 +4,52 @@
 import java.util.Map;
 
 public class NodeTypeInfo {
-	String type;
-	String templateFileName;
-	List<String> derivedFrom;
-	boolean isNested;
-	Map<String, Object> mappedToscaTemplate;
-	
-	public NodeTypeInfo getUnmarkedCopy(){
-		NodeTypeInfo unmarked = new NodeTypeInfo();
-		unmarked.type = this.type;
-		unmarked.templateFileName = this.templateFileName;
-		unmarked.derivedFrom = this.derivedFrom;
-		unmarked.isNested = false;
-		unmarked.mappedToscaTemplate = this.mappedToscaTemplate;
-		return unmarked;
-	}
-	
-	public String getType() {
-		return type;
-	}
-	public void setType(String type) {
-		this.type = type;
-	}
-	public String getTemplateFileName() {
-		return templateFileName;
-	}
-	public void setTemplateFileName(String templateFileName) {
-		this.templateFileName = templateFileName;
-	}
-	public List<String> getDerivedFrom() {
-		return derivedFrom;
-	}
-	public void setDerivedFrom(List<String> derivedFrom) {
-		this.derivedFrom = derivedFrom;
-	}
-	public boolean isNested() {
-		return isNested;
-	}
-	public void setNested(boolean isNested) {
-		this.isNested = isNested;
-	}
+    String type;
+    String templateFileName;
+    List<String> derivedFrom;
+    boolean isNested;
+    Map<String, Object> mappedToscaTemplate;
 
-	public Map<String, Object> getMappedToscaTemplate() {
-		return mappedToscaTemplate;
-	}
+    public NodeTypeInfo getUnmarkedCopy(){
+        NodeTypeInfo unmarked = new NodeTypeInfo();
+        unmarked.type = this.type;
+        unmarked.templateFileName = this.templateFileName;
+        unmarked.derivedFrom = this.derivedFrom;
+        unmarked.isNested = false;
+        unmarked.mappedToscaTemplate = this.mappedToscaTemplate;
+        return unmarked;
+    }
 
-	public void setMappedToscaTemplate(Map<String, Object> mappedToscaTemplate) {
-		this.mappedToscaTemplate = mappedToscaTemplate;
-	}
+    public String getType() {
+        return type;
+    }
+    public void setType(String type) {
+        this.type = type;
+    }
+    public String getTemplateFileName() {
+        return templateFileName;
+    }
+    public void setTemplateFileName(String templateFileName) {
+        this.templateFileName = templateFileName;
+    }
+    public List<String> getDerivedFrom() {
+        return derivedFrom;
+    }
+    public void setDerivedFrom(List<String> derivedFrom) {
+        this.derivedFrom = derivedFrom;
+    }
+    public boolean isNested() {
+        return isNested;
+    }
+    public void setNested(boolean isNested) {
+        this.isNested = isNested;
+    }
+
+    public Map<String, Object> getMappedToscaTemplate() {
+        return mappedToscaTemplate;
+    }
+
+    public void setMappedToscaTemplate(Map<String, Object> mappedToscaTemplate) {
+        this.mappedToscaTemplate = mappedToscaTemplate;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.java
index 4455920..a2fe8b2 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.java
@@ -7,9 +7,9 @@
  * 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.
@@ -28,59 +28,59 @@
 
 /**
  * Defines an operation available to manage particular aspects of the Node Type.
- *
+ * 
  * @author esofer
  */
 public class Operation extends OperationDataDefinition implements IOperationParameter {
 
 
 
-	private boolean definition;
+    private boolean definition;
 
-	/**
-	 * <p>
-	 * Jackson DeSerialization workaround constructor to create an operation
-	 * with no arguments.
-	 * </p>
-	 *
-	 * @param emptyString
-	 *            The empty string provided by jackson.
-	 */
-	public Operation() {
-		super();
-	}
+    /**
+     * <p>
+     * Jackson DeSerialization workaround constructor to create an operation
+     * with no arguments.
+     * </p>
+     *
+     * @param emptyString
+     *            The empty string provided by jackson.
+     */
+    public Operation() {
+        super();
+    }
 
-	public Operation(OperationDataDefinition p) {
-		super(p);
-	}
+    public Operation(OperationDataDefinition p) {
+        super(p);
+    }
 
-	public Operation(ArtifactDataDefinition implementation, String description,
+    public Operation(ArtifactDataDefinition implementation, String description,
 					 ListDataDefinition<OperationInputDefinition> inputs,
 					 ListDataDefinition<OperationOutputDefinition> outputs) {
-		super(description);
-		setImplementation(implementation);
-		setInputs(inputs);
+        super(description);
+        setImplementation(implementation);
+        setInputs(inputs);
 		setOutputs(outputs);
-	}
+    }
 
-	@Override
-	public boolean isDefinition() {
-		return false;
-	}
+    @Override
+    public boolean isDefinition() {
+        return false;
+    }
 
-	public void setDefinition(boolean definition) {
-		this.definition = definition;
-	}
+    public void setDefinition(boolean definition) {
+        this.definition = definition;
+    }
 
-	@Override
-	public String toString() {
-		return "Operation [definition=" + definition + "]";
-	}
+    @Override
+    public String toString() {
+        return "Operation [definition=" + definition + "]";
+    }
 
-	public ArtifactDefinition getImplementationArtifact(){
-		if ( getImplementation() != null ){
-			return new ArtifactDefinition(getImplementation());
-		}
-		return null;
-	}
+    public ArtifactDefinition getImplementationArtifact(){
+        if ( getImplementation() != null ){
+            return new ArtifactDefinition(getImplementation());
+        }
+        return null;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java
index 3b07081..f975806 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java
@@ -23,39 +23,39 @@
 import java.util.Map;
 
 public class ParsedToscaYamlInfo {
-	Map<String, InputDefinition> inputs;
+    Map<String, InputDefinition> inputs;
 
-	Map<String, UploadComponentInstanceInfo> instances;
+    Map<String, UploadComponentInstanceInfo> instances;
 
-	Map<String, GroupDefinition> groups;
+    Map<String, GroupDefinition> groups;
 
-	public Map<String, UploadComponentInstanceInfo> getInstances() {
-		return instances;
-	}
+    public Map<String, UploadComponentInstanceInfo> getInstances() {
+        return instances;
+    }
 
-	public void setInstances(Map<String, UploadComponentInstanceInfo> instances) {
-		this.instances = instances;
-	}
+    public void setInstances(Map<String, UploadComponentInstanceInfo> instances) {
+        this.instances = instances;
+    }
 
-	public Map<String, GroupDefinition> getGroups() {
-		return groups;
-	}
+    public Map<String, GroupDefinition> getGroups() {
+        return groups;
+    }
 
-	public void setGroups(Map<String, GroupDefinition> groups) {
-		this.groups = groups;
-	}
+    public void setGroups(Map<String, GroupDefinition> groups) {
+        this.groups = groups;
+    }
 
-	public Map<String, InputDefinition> getInputs() {
-		return inputs;
-	}
+    public Map<String, InputDefinition> getInputs() {
+        return inputs;
+    }
 
-	public void setInputs(Map<String, InputDefinition> inputs) {
-		this.inputs = inputs;
-	}
+    public void setInputs(Map<String, InputDefinition> inputs) {
+        this.inputs = inputs;
+    }
 
-	@Override
-	public String toString() {
-		return "ParsedToscaYamlInfo [inputs=" + inputs + ", instances=" + instances + ", groups=" + groups + "]";
-	}
+    @Override
+    public String toString() {
+        return "ParsedToscaYamlInfo [inputs=" + inputs + ", instances=" + instances + ", groups=" + groups + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.java
index e609f49..a8bf797 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.java
@@ -22,38 +22,38 @@
 
 public class Point {
 
-	String x;
-	String y;
+    String x;
+    String y;
 
-	public Point() {
-		super();
-	}
+    public Point() {
+        super();
+    }
 
-	public Point(String x, String y) {
-		super();
-		this.x = x;
-		this.y = y;
-	}
+    public Point(String x, String y) {
+        super();
+        this.x = x;
+        this.y = y;
+    }
 
-	public String getX() {
-		return x;
-	}
+    public String getX() {
+        return x;
+    }
 
-	public void setX(String x) {
-		this.x = x;
-	}
+    public void setX(String x) {
+        this.x = x;
+    }
 
-	public String getY() {
-		return y;
-	}
+    public String getY() {
+        return y;
+    }
 
-	public void setY(String y) {
-		this.y = y;
-	}
+    public void setY(String y) {
+        this.y = y;
+    }
 
-	@Override
-	public String toString() {
-		return "Point [x=" + x + ", y=" + y + "]";
-	}
+    @Override
+    public String toString() {
+        return "Point [x=" + x + ", y=" + y + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyDefinition.java
index 22d69cd..17e422b 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyDefinition.java
@@ -1,65 +1,60 @@
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.stream.Collectors;
-
 import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertiesOwner;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
 /**
  * public class representing the component policy
  */
-public class PolicyDefinition extends PolicyDataDefinition implements Serializable, PropertiesOwner {
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 8433981810801300209L;
-	
-	/**
-	 * public constructor by default
-	 */
-	public PolicyDefinition() {
-		super();
-	}
+public class PolicyDefinition extends PolicyDataDefinition implements PropertiesOwner {
 
-	/**
-	 * public constructor from superclass
-	 * @param policy
-	 */
-	public PolicyDefinition(Map<String, Object> policy) {
-		super(policy);
-	}
+    /**
+     * public constructor by default
+     */
+    public PolicyDefinition() {
+        super();
+    }
 
-	/**
-	 * public copy constructor
-	 * @param other
-	 */
-	public PolicyDefinition(PolicyDataDefinition other) {
-		super(other);
-	}
-	
-	/**
-	 * public converter constructor 
-	 * builds PolicyDefinition object based on received PolicyTypeDefinition object
-	 * @param policyType
-	 */
-	public PolicyDefinition(PolicyTypeDefinition policyType) {
-		this.setPolicyTypeName(policyType.getType());
-		this.setPolicyTypeUid(policyType.getUniqueId());
-		this.setDerivedFrom(policyType.getDerivedFrom());
-		this.setDescription(policyType.getDescription());
-		this.setVersion(policyType.getVersion());
-		if (policyType.getProperties() != null) {
-			this.setProperties(policyType.getProperties().stream().map(PropertyDataDefinition::new).collect(Collectors.toList()));
-		}
-		this.setTargets(new HashMap<>());
+    /**
+     * public constructor from superclass
+     * @param policy
+     */
+    public PolicyDefinition(Map<String, Object> policy) {
+        super(policy);
+    }
 
-	}
+    /**
+     * public copy constructor
+     * @param other
+     */
+    public PolicyDefinition(PolicyDataDefinition other) {
+        super(other);
+    }
 
-	@Override
-	public String getNormalizedName() {
-		return getName();
-	}
+    /**
+     * public converter constructor
+     * builds PolicyDefinition object based on received PolicyTypeDefinition object
+     * @param policyType
+     */
+    public PolicyDefinition(PolicyTypeDefinition policyType) {
+        this.setPolicyTypeName(policyType.getType());
+        this.setPolicyTypeUid(policyType.getUniqueId());
+        this.setDerivedFrom(policyType.getDerivedFrom());
+        this.setDescription(policyType.getDescription());
+        this.setVersion(policyType.getVersion());
+        if (policyType.getProperties() != null) {
+            this.setProperties(policyType.getProperties().stream().map(PropertyDataDefinition::new).collect(Collectors.toList()));
+        }
+        this.setTargets(new HashMap<>());
+
+    }
+
+    @Override
+    public String getNormalizedName() {
+        return getName();
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.java
index 9483d5c..0cfdf19 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.java
@@ -20,10 +20,10 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.elements.PolicyTypeDataDefinition;
 
+import java.util.List;
+
 /**
  * Specifies the policy type that the Node Type exposes.
  */
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.java
index 12e6eaf..66062cf 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.java
@@ -20,61 +20,61 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.elements.ProductMetadataDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 
+import java.util.List;
+
 public class Product extends Component {
 
-	public Product() {
-		super(new ProductMetadataDefinition());
-		this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.PRODUCT);
-	}
+    public Product() {
+        super(new ProductMetadataDefinition());
+        this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.PRODUCT);
+    }
 
-	public Product(ProductMetadataDefinition productMetadataDefinition) {
-		super(productMetadataDefinition);
-		this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.PRODUCT);
-	}
+    public Product(ProductMetadataDefinition productMetadataDefinition) {
+        super(productMetadataDefinition);
+        this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.PRODUCT);
+    }
 
-	public String getFullName() {
-		return getProductMetadataDefinition().getFullName();
-	}
+    public String getFullName() {
+        return getProductMetadataDefinition().getFullName();
+    }
 
-	public void setFullName(String fullName) {
-		getProductMetadataDefinition().setFullName(fullName);
-	}
+    public void setFullName(String fullName) {
+        getProductMetadataDefinition().setFullName(fullName);
+    }
 
-	public String getInvariantUUID() {
-		return getProductMetadataDefinition().getInvariantUUID();
-	}
+    public String getInvariantUUID() {
+        return getProductMetadataDefinition().getInvariantUUID();
+    }
 
-	public void setInvariantUUID(String invariantUUID) {
-		getProductMetadataDefinition().setInvariantUUID(invariantUUID);
-	}
+    public void setInvariantUUID(String invariantUUID) {
+        getProductMetadataDefinition().setInvariantUUID(invariantUUID);
+    }
 
-	public List<String> getContacts() {
-		return getProductMetadataDefinition().getContacts();
-	}
+    public List<String> getContacts() {
+        return getProductMetadataDefinition().getContacts();
+    }
 
-	public void setContacts(List<String> contacts) {
-		getProductMetadataDefinition().setContacts(contacts);
-	}
+    public void setContacts(List<String> contacts) {
+        getProductMetadataDefinition().setContacts(contacts);
+    }
 
-	public void addContact(String contact) {
-		getProductMetadataDefinition().addContact(contact);
-	}
+    public void addContact(String contact) {
+        getProductMetadataDefinition().addContact(contact);
+    }
 
-	public Boolean getIsActive() {
-		return getProductMetadataDefinition().getIsActive();
-	}
+    public Boolean getIsActive() {
+        return getProductMetadataDefinition().getIsActive();
+    }
 
-	public void setIsActive(Boolean isActive) {
-		getProductMetadataDefinition().setIsActive(isActive);
-	}
+    public void setIsActive(Boolean isActive) {
+        getProductMetadataDefinition().setIsActive(isActive);
+    }
 
-	private ProductMetadataDataDefinition getProductMetadataDefinition() {
-		return (ProductMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition();
-	}
+    private ProductMetadataDataDefinition getProductMetadataDefinition() {
+        return (ProductMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition();
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.java
index dc454d1..71d54d9 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.java
@@ -24,12 +24,12 @@
 
 public class ProductMetadataDefinition extends ComponentMetadataDefinition {
 
-	public ProductMetadataDefinition() {
-		super();
-		this.componentMetadataDataDefinition = new ProductMetadataDataDefinition();
-	}
+    public ProductMetadataDefinition() {
+        super();
+        this.componentMetadataDataDefinition = new ProductMetadataDataDefinition();
+    }
 
-	public ProductMetadataDefinition(ProductMetadataDataDefinition component) {
-		super(component);
-	}
+    public ProductMetadataDefinition(ProductMetadataDataDefinition component) {
+        super(component);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java
index b1e1552..9a5c52d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java
@@ -26,9 +26,9 @@
 
 public interface PropertyConstraint {
 
-	void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException;
+    void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException;
 
-	void validate(Object propertyValue) throws ConstraintViolationException;
+    void validate(Object propertyValue) throws ConstraintViolationException;
 
-	void validate(ToscaType toscaType, String propertyTextValue) throws ConstraintViolationException;
+    void validate(ToscaType toscaType, String propertyTextValue) throws ConstraintViolationException;
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java
index 7cd57be..e09fe41 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java
@@ -20,166 +20,151 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 
+import java.util.List;
+
 
 public class PropertyDefinition extends PropertyDataDefinition
-		implements IOperationParameter, IComplexDefaultValue, Serializable {
+        implements IOperationParameter, IComplexDefaultValue {
 
-	
-	/**The enumeration presents the list of property names with specific behavior 
-	 * @author rbetzer
-	 *
-	 */
-	public enum PropertyNames {
-		
-		MIN_INSTANCES("min_vf_module_instances", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL),
-		MAX_INSTANCES("max_vf_module_instances", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL),
-		INITIAL_COUNT("initial_count", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL),
-		VF_MODULE_LABEL("vf_module_label", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_RESOURCE_LEVEL),
-		VF_MODULE_DESCRIPTION("vf_module_description", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_RESOURCE_LEVEL),
-		NETWORK_ROLE("network_role", GroupInstancePropertyValueUpdateBehavior.NOT_RELEVANT),
-		AVAILABILTY_ZONE_COUNT("availability_zone_count", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL),
-		VFC_LIST("vfc_list", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL);
-		
-		private final String propertyName;
-		private final GroupInstancePropertyValueUpdateBehavior updateBehavior;
-		
-		private PropertyNames(String propertyName,GroupInstancePropertyValueUpdateBehavior updateBehavior){
-			this.propertyName = propertyName;
-			this.updateBehavior = updateBehavior;
-		}
-		
-		public String getPropertyName() {
-			return propertyName;
-		}
-		
-		public GroupInstancePropertyValueUpdateBehavior getUpdateBehavior() {
-			return updateBehavior;
-		}
-		/**
-		 * finds PropertyNames according received string name
-		 * @param name
-		 * @return
-		 */
-		public static PropertyNames findName(String name){
-			for (PropertyNames e : PropertyNames.values()) {
-				if (e.getPropertyName().equals(name)) {
-					return e;
-				}
-			}
-			return null;
-		}
-	}
-	/**
-	 * The enumeration presents the list of highest levels for which update property value is allowed
-	 * @author nsheshukov
-	 *
-	 */
-	public enum GroupInstancePropertyValueUpdateBehavior{
-		NOT_RELEVANT("NOT_RELEVANT", -1),
-		UPDATABLE_ON_RESOURCE_LEVEL("UPDATABLE_ON_VF_LEVEL", 0),
-		UPDATABLE_ON_SERVICE_LEVEL("UPDATABLE_ON_SERVICE_LEVEL", 1);
-		
-		private final String levelName;
-		private final int levelNumber;
-		
-		private GroupInstancePropertyValueUpdateBehavior(String name, int levelNumber){
-			this.levelName = name;
-			this.levelNumber = levelNumber;
-		}
 
-		public String getLevelName() {
-			return levelName;
-		}
+    /**The enumeration presents the list of property names with specific behavior
+     * @author rbetzer
+     *
+     */
+    public enum PropertyNames {
 
-		public int getLevelNumber() {
-			return levelNumber;
-		}
-	}
-	
-	private static final long serialVersionUID = 188403656600317269L;
+        MIN_INSTANCES("min_vf_module_instances", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL),
+        MAX_INSTANCES("max_vf_module_instances", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL),
+        INITIAL_COUNT("initial_count", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL),
+        VF_MODULE_LABEL("vf_module_label", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_RESOURCE_LEVEL),
+        VF_MODULE_DESCRIPTION("vf_module_description", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_RESOURCE_LEVEL),
+        NETWORK_ROLE("network_role", GroupInstancePropertyValueUpdateBehavior.NOT_RELEVANT),
+        AVAILABILTY_ZONE_COUNT("availability_zone_count", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL),
+        VFC_LIST("vfc_list", GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL);
 
-	private List<PropertyConstraint> constraints;
-	// private Schema schema;
-	// private String status;
+        private String propertyName;
+        private GroupInstancePropertyValueUpdateBehavior updateBehavior;
+
+        private PropertyNames(String propertyName,GroupInstancePropertyValueUpdateBehavior updateBehavior){
+            this.propertyName = propertyName;
+            this.updateBehavior = updateBehavior;
+        }
+
+        public String getPropertyName() {
+            return propertyName;
+        }
+
+        public GroupInstancePropertyValueUpdateBehavior getUpdateBehavior() {
+            return updateBehavior;
+        }
+        /**
+         * finds PropertyNames according received string name
+         * @param name
+         * @return
+         */
+        public static PropertyNames findName(String name){
+            for (PropertyNames e : PropertyNames.values()) {
+                if (e.getPropertyName().equals(name)) {
+                    return e;
+                }
+            }
+            return null;
+        }
+    }
+    /**
+     * The enumeration presents the list of highest levels for which update property value is allowed
+     * @author nsheshukov
+     *
+     */
+    public enum GroupInstancePropertyValueUpdateBehavior{
+        NOT_RELEVANT("NOT_RELEVANT", -1),
+        UPDATABLE_ON_RESOURCE_LEVEL("UPDATABLE_ON_VF_LEVEL", 0),
+        UPDATABLE_ON_SERVICE_LEVEL("UPDATABLE_ON_SERVICE_LEVEL", 1);
+
+        String levelName;
+        int levelNumber;
+
+        private GroupInstancePropertyValueUpdateBehavior(String name, int levelNumber){
+            this.levelName = name;
+            this.levelNumber = levelNumber;
+        }
+
+        public String getLevelName() {
+            return levelName;
+        }
+
+        public int getLevelNumber() {
+            return levelNumber;
+        }
+    }
+
+    private List<PropertyConstraint> constraints;
+
+    public PropertyDefinition() {
+        super();
+    }
+
+    public PropertyDefinition(PropertyDataDefinition p) {
+        super(p);
+    }
+
+    public PropertyDefinition(PropertyDefinition pd) {
+        super(pd);
+        this.setConstraints(pd.getConstraints());
+    }
+
+    public List<PropertyConstraint> getConstraints() {
+        return constraints;
+    }
+
+    public void setConstraints(List<PropertyConstraint> constraints) {
+        this.constraints = constraints;
+    }
 
 
 
-	
-	public PropertyDefinition() {
-		super();
-	}
+    @Override
+    public String toString() {
+        return  "PropertyDefinition [ " + super.toString() + ", name=" + getName() + ", constraints="
+                + constraints + "]]";
+    }
 
-	public PropertyDefinition(PropertyDataDefinition p) {
-		super(p);
-	}
+    @Override
+    public boolean isDefinition() {
+        return false;
+    }
 
-	public PropertyDefinition(PropertyDefinition pd) {
-		super(pd);	
-		this.setConstraints(pd.getConstraints());		
-		//status = pd.status;
-		
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + ((constraints == null) ? 0 : constraints.hashCode());
+        result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
+        return result;
+    }
 
-	public List<PropertyConstraint> getConstraints() {
-		return constraints;
-	}
-
-	public void setConstraints(List<PropertyConstraint> constraints) {
-		this.constraints = constraints;
-	}
-
-
-
-	@Override
-	public String toString() {
-		return super.toString() + " [name=" + getName() + ", constraints="
-				+ constraints + "]]";
-	}
-
-	@Override
-	public boolean isDefinition() {
-		return false;
-	}
-
-	public void setDefinition(boolean definition) {
-		super.setDefinition(definition);
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + ((constraints == null) ? 0 : constraints.hashCode());
-		result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
-		//result = prime * result + ((status == null) ? 0 : status.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		PropertyDefinition other = (PropertyDefinition) obj;
-		if (constraints == null) {
-			if (other.constraints != null)
-				return false;
-		} else if (!constraints.equals(other.constraints))
-			return false;
-		if (getName() == null) {
-			if (other.getName() != null)
-				return false;
-		} else if (!getName().equals(other.getName()))
-			return false;
-		return true;
-	}
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        PropertyDefinition other = (PropertyDefinition) obj;
+        if (constraints == null) {
+            if (other.constraints != null)
+                return false;
+        } else if (!constraints.equals(other.constraints))
+            return false;
+        if (getName() == null) {
+            if (other.getName() != null)
+                return false;
+        } else if (!getName().equals(other.getName()))
+            return false;
+        return true;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.java
index e46c433..cd94f2f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.java
@@ -22,43 +22,43 @@
 
 public class PropertyScope {
 
-	private String name;
+    private String name;
 
-	public String getName() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((name == null) ? 0 : name.hashCode());
-		return result;
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        return result;
+    }
 
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj) {
-			return true;
-		}
-		if (obj == null) {
-			return false;
-		}
-		if (getClass() != obj.getClass()) {
-			return false;
-		}
-		PropertyScope other = (PropertyScope) obj;
-		if (name == null) {
-			if (other.getClass() != null) {
-				return false;
-			}
-		} else if (!name.equals(other.getName())) {
-			return false;
-		}
-		return true;
-	}
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PropertyScope other = (PropertyScope) obj;
+        if (name == null) {
+            if (other.getClass() != null) {
+                return false;
+            }
+        } else if (!name.equals(other.getName())) {
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.java
index bc22e55..a10c1e0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.java
@@ -24,19 +24,19 @@
 
 public class PropertyValueDefinition extends InputsValueDataDefinition implements IOperationParameter {
 
-	public PropertyValueDefinition() {
-		super();
-	}
+    public PropertyValueDefinition() {
+        super();
+    }
 
-	public PropertyValueDefinition(String name, String value) {
-		super(name, value);
+    public PropertyValueDefinition(String name, String value) {
+        super(name, value);
 
-	}
+    }
 
-	@Override
-	public boolean isDefinition() {
-		// TODO Auto-generated method stub
-		return false;
-	}
+    @Override
+    public boolean isDefinition() {
+        // TODO Auto-generated method stub
+        return false;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java
index 6028809..0d07027 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java
@@ -20,28 +20,21 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
+public class RelationshipImpl {
 
-public class RelationshipImpl implements Serializable {
+    private String type;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -8272341490256251337L;
+    public String getType() {
+        return type;
+    }
 
-	private String type;
+    public void setType(String type) {
+        this.type = type;
+    }
 
-	public String getType() {
-		return type;
-	}
-
-	public void setType(String type) {
-		this.type = type;
-	}
-
-	@Override
-	public String toString() {
-		return "RelationshipImpl [type=" + type + "]";
-	}
+    @Override
+    public String toString() {
+        return "RelationshipImpl [type=" + type + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipInfo.java
index 02c9f70..f67d8bb 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipInfo.java
@@ -20,142 +20,138 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-
 import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
 
-public class RelationshipInfo implements Serializable {
+public class RelationshipInfo {
 
-	private static final long serialVersionUID = -5763126570618602135L;
+    private String requirement;
+    private String capabilityOwnerId;
+    private String requirementOwnerId;
+    private String id;
 
-	private String requirement;
-	private String capabilityOwnerId;
-	private String requirementOwnerId;
-	private String id;
+    private RelationshipImpl relationship;
 
-	private RelationshipImpl relationship;
+    private String capability;
 
-	private String capability;
+    private String capabilityUid;
+    private String requirementUid;
 
-	private String capabilityUid;
-	private String requirementUid;
+    public RelationshipInfo() {
+        super();
+    }
 
-	public RelationshipInfo() {
-		super();
-	}
+    public RelationshipInfo(String requirement, RelationshipImpl relationship) {
+        super();
+        this.requirement = requirement;
+        this.relationship = relationship;
+    }
 
-	public RelationshipInfo(String requirement, RelationshipImpl relationship) {
-		super();
-		this.requirement = requirement;
-		this.relationship = relationship;
-	}
+    public RelationshipInfo(String requirement, RelationshipImpl relationship, String capability) {
+        super();
+        this.requirement = requirement;
+        this.relationship = relationship;
+        this.capability = capability;
+    }
 
-	public RelationshipInfo(String requirement, RelationshipImpl relationship, String capability) {
-		super();
-		this.requirement = requirement;
-		this.relationship = relationship;
-		this.capability = capability;
-	}
+    public String getRequirement() {
+        return requirement;
+    }
 
-	public String getRequirement() {
-		return requirement;
-	}
+    public void setRequirement(String requirement) {
+        this.requirement = requirement;
+    }
 
-	public void setRequirement(String requirement) {
-		this.requirement = requirement;
-	}
+    public String getCapabilityOwnerId() {
+        return capabilityOwnerId;
+    }
 
-	public String getCapabilityOwnerId() {
-		return capabilityOwnerId;
-	}
+    public void setCapabilityOwnerId(String capabilityOwnerId) {
+        this.capabilityOwnerId = capabilityOwnerId;
+    }
 
-	public void setCapabilityOwnerId(String capabilityOwnerId) {
-		this.capabilityOwnerId = capabilityOwnerId;
-	}
+    public String getRequirementOwnerId() {
+        return requirementOwnerId;
+    }
 
-	public String getRequirementOwnerId() {
-		return requirementOwnerId;
-	}
+    public void setRequirementOwnerId(String requirementOwnerId) {
+        this.requirementOwnerId = requirementOwnerId;
+    }
 
-	public void setRequirementOwnerId(String requirementOwnerId) {
-		this.requirementOwnerId = requirementOwnerId;
-	}
+    public RelationshipImpl getRelationship() {
+        return relationship;
+    }
 
-	public RelationshipImpl getRelationship() {
-		return relationship;
-	}
+    public void setRelationships(RelationshipImpl relationship) {
+        this.relationship = relationship;
+    }
 
-	public void setRelationships(RelationshipImpl relationship) {
-		this.relationship = relationship;
-	}
+    public String getCapability() {
+        return capability;
+    }
 
-	public String getCapability() {
-		return capability;
-	}
+    public void setCapability(String capability) {
+        this.capability = capability;
+    }
 
-	public void setCapability(String capability) {
-		this.capability = capability;
-	}
+    public String getCapabilityUid() {
+        return capabilityUid;
+    }
 
-	public String getCapabilityUid() {
-		return capabilityUid;
-	}
+    public void setCapabilityUid(String capabilityUid) {
+        this.capabilityUid = capabilityUid;
+    }
 
-	public void setCapabilityUid(String capabilityUid) {
-		this.capabilityUid = capabilityUid;
-	}
+    public String getRequirementUid() {
+        return requirementUid;
+    }
 
-	public String getRequirementUid() {
-		return requirementUid;
-	}
+    public void setRequirementUid(String requirementUid) {
+        this.requirementUid = requirementUid;
+    }
 
-	public void setRequirementUid(String requirementUid) {
-		this.requirementUid = requirementUid;
-	}
+    public String getId() {
+        return id;
+    }
 
-	public String getId() {
-		return id;
-	}
+    public void setId(String id) {
+        this.id = id;
+    }
 
-	public void setId(String id) {
-		this.id = id;
-	}
+    @Override
+    public String toString() {
+        return "RequirementAndRelationshipPair [requirement=" + requirement + ", relationship=" + relationship
+                + ", capability=" + capability + "]";
+    }
 
-	@Override
-	public String toString() {
-		return "RequirementAndRelationshipPair [requirement=" + requirement + ", relationship=" + relationship
-				+ ", capability=" + capability + "]";
-	}
-
-	public boolean equalsTo( RelationshipInstDataDefinition savedRelation){
-		if ( savedRelation == null ){
-			return false;
-		}
-		if(getRelationship().getType() == null ){
-			if(savedRelation.getType() != null){
-				return false;
-			}
-		}
-		else { 
-			if ( !savedRelation.getType().equals(this.getRelationship().getType()) ){
-				return false;
-			}	
-		}
-		if ( !savedRelation.getCapabilityOwnerId().equals(this.getCapabilityOwnerId()) ){
-			return false;
-		}
-		if ( !savedRelation.getRequirementOwnerId().equals(this.getRequirementOwnerId()) ){
-			return false;
-		}
-		if ( !savedRelation.getRequirementId().equals(this.getRequirementUid()) ){
-			return false;
-		}
-		if ( !savedRelation.getCapabilityId().equals(this.getCapabilityUid()) ){
-			return false;
-		}
-		if ( !savedRelation.getRequirement().equals(this.getRequirement()) ){
-			return false;
-		}
-		return true;
-	}
+    public boolean equalsTo( RelationshipInstDataDefinition savedRelation){
+        if ( savedRelation == null ){
+            return false;
+        }
+        if(getRelationship().getType() == null ){
+            if(savedRelation.getType() != null){
+                return false;
+            }
+        }
+        else {
+            if ( !savedRelation.getType().equals(this.getRelationship().getType()) ){
+                return false;
+            }
+        }
+        if ( !savedRelation.getCapabilityOwnerId().equals(this.getCapabilityOwnerId()) ){
+            return false;
+        }
+        if ( !savedRelation.getRequirementOwnerId().equals(this.getRequirementOwnerId()) ){
+            return false;
+        }
+        if ( !savedRelation.getRequirementId().equals(this.getRequirementUid()) ){
+            return false;
+        }
+        if ( !savedRelation.getCapabilityId().equals(this.getCapabilityUid()) ){
+            return false;
+        }
+        if ( !savedRelation.getRequirement().equals(this.getRequirement()) ){
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java
index 345f272..615542f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java
@@ -20,28 +20,42 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
+public class RequirementCapabilityRelDef extends TargetCapabilityRelDef {
 
-public class RequirementCapabilityRelDef extends TargetCapabilityRelDef implements Serializable {
+    private String fromNode;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -6396265049494824741L;
+    private boolean originUI;
 
-	private String fromNode;
+    public RequirementCapabilityRelDef() {
+    }
 
-	public String getFromNode() {
-		return fromNode;
-	}
+    public RequirementCapabilityRelDef(RequirementCapabilityRelDef another) {
+        super(another.getToNode(), another.getRelationships());
 
-	public void setFromNode(String fromNode) {
-		this.fromNode = fromNode;
-	}
+        fromNode = another.getFromNode();
+        originUI = another.isOriginUI();
+    }
 
-	@Override
-	public String toString() {
-		return "RequirementCapabilityRelDef [fromNode=" + fromNode + ", toString()=" + super.toString() + "]";
-	}
+
+    public String getFromNode() {
+        return fromNode;
+    }
+
+    public void setFromNode(String fromNode) {
+        this.fromNode = fromNode;
+    }
+
+    public boolean isOriginUI() {
+        return originUI;
+    }
+
+    public void setOriginUI(boolean originUI) {
+        this.originUI = originUI;
+    }
+
+    @Override
+    public String toString() {
+        return "RequirementCapabilityRelDef [fromNode=" + fromNode + ", originUI=" + originUI + ", " + super.toString() + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java
index a1a485d..d2400a7 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java
@@ -20,27 +20,22 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-
 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
 
 /**
  * Specifies the requirements that the Node Type exposes.
  */
-public class RequirementDefinition extends RequirementDataDefinition implements Serializable {
+public class RequirementDefinition extends RequirementDataDefinition {
 
-	public RequirementDefinition(){
-		super();
-	}
-	
-	public RequirementDefinition(RequirementDefinition other) {
-		super(other);
-	}
-	
-	public RequirementDefinition(RequirementDataDefinition requirementDataDefinition) {
-		super(requirementDataDefinition);
-	}
-	
-	private static final long serialVersionUID = -1899506746481882719L;
+    public RequirementDefinition(){
+        super();
+    }
 
+    public RequirementDefinition(RequirementDefinition other) {
+        super(other);
+    }
+
+    public RequirementDefinition(RequirementDataDefinition requirementDataDefinition) {
+        super(requirementDataDefinition);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.java
index eb6bd01..bf394fd 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.java
@@ -24,53 +24,53 @@
 
 public class RequirementImplDef {
 
-	private String uniqueId;
+    private String uniqueId;
 
-	/**
-	 * node type(mandatory). Unique id of the node we choose.
-	 */
-	private String nodeId;
+    /**
+     * node type(mandatory). Unique id of the node we choose.
+     */
+    private String nodeId;
 
-	private Map<String, CapabiltyInstance> requirementProperties;
+    private Map<String, CapabiltyInstance> requirementProperties;
 
-	private Point point;
+    private Point point;
 
-	public String getNodeId() {
-		return nodeId;
-	}
+    public String getNodeId() {
+        return nodeId;
+    }
 
-	public void setNodeId(String nodeId) {
-		this.nodeId = nodeId;
-	}
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
 
-	public String getUniqueId() {
-		return uniqueId;
-	}
+    public String getUniqueId() {
+        return uniqueId;
+    }
 
-	public void setUniqueId(String uniqueId) {
-		this.uniqueId = uniqueId;
-	}
+    public void setUniqueId(String uniqueId) {
+        this.uniqueId = uniqueId;
+    }
 
-	public Map<String, CapabiltyInstance> getRequirementProperties() {
-		return requirementProperties;
-	}
+    public Map<String, CapabiltyInstance> getRequirementProperties() {
+        return requirementProperties;
+    }
 
-	public void setRequirementProperties(Map<String, CapabiltyInstance> requirementProperties) {
-		this.requirementProperties = requirementProperties;
-	}
+    public void setRequirementProperties(Map<String, CapabiltyInstance> requirementProperties) {
+        this.requirementProperties = requirementProperties;
+    }
 
-	public Point getPoint() {
-		return point;
-	}
+    public Point getPoint() {
+        return point;
+    }
 
-	public void setPoint(Point point) {
-		this.point = point;
-	}
+    public void setPoint(Point point) {
+        this.point = point;
+    }
 
-	@Override
-	public String toString() {
-		return "RequirementImplDef [uniqueId=" + uniqueId + ", nodeId=" + nodeId + ", requirementProperties="
-				+ requirementProperties + ", point=" + point + "]";
-	}
+    @Override
+    public String toString() {
+        return "RequirementImplDef [uniqueId=" + uniqueId + ", nodeId=" + nodeId + ", requirementProperties="
+                + requirementProperties + ", point=" + point + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.java
index 14f4463..0aa8534 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.java
@@ -25,35 +25,35 @@
  */
 public class RequirementInstance {
 
-	/**
-	 * specify the resource instance name as appears in the service
-	 */
-	private String node;
+    /**
+     * specify the resource instance name as appears in the service
+     */
+    private String node;
 
-	/**
-	 * specify the relationship impl
-	 */
-	private RelationshipImpl relationship;
+    /**
+     * specify the relationship impl
+     */
+    private RelationshipImpl relationship;
 
-	public String getNode() {
-		return node;
-	}
+    public String getNode() {
+        return node;
+    }
 
-	public void setNode(String node) {
-		this.node = node;
-	}
+    public void setNode(String node) {
+        this.node = node;
+    }
 
-	public RelationshipImpl getRelationship() {
-		return relationship;
-	}
+    public RelationshipImpl getRelationship() {
+        return relationship;
+    }
 
-	public void setRelationship(RelationshipImpl relationship) {
-		this.relationship = relationship;
-	}
+    public void setRelationship(RelationshipImpl relationship) {
+        this.relationship = relationship;
+    }
 
-	@Override
-	public String toString() {
-		return "RequirementInstance [node=" + node + ", relationship=" + relationship + "]";
-	}
+    @Override
+    public String toString() {
+        return "RequirementInstance [node=" + node + ", relationship=" + relationship + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java
index 58efa56..e15f115 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java
@@ -20,11 +20,6 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.utils.MapUtil;
 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
@@ -32,300 +27,286 @@
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
 
-public class Resource extends Component implements Serializable {
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 
-	private static final long serialVersionUID = -6811540567661368482L;
-	public static final String ROOT_RESOURCE = "tosca.nodes.Root";
+public class Resource extends Component {
 
-	public Resource() {
-		super(new ResourceMetadataDefinition());
-		this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.RESOURCE);
-	}
+		
+			
+    private List<String> derivedFrom;
 
-	public Resource(ComponentMetadataDefinition componentMetadataDefinition) {
-		super(componentMetadataDefinition);
-		if(this.getComponentMetadataDefinition().getMetadataDataDefinition() == null) {
-			this.getComponentMetadataDefinition().componentMetadataDataDefinition = new ResourceMetadataDataDefinition();
-		}
-		this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.RESOURCE);
-	}
+    private List<String> derivedList;
 
-	private List<String> derivedFrom;
+    private List<PropertyDefinition> properties;
 
-	private List<String> derivedList;
+    private List<PropertyDefinition> attributes;
 
-	private List<PropertyDefinition> properties;
+    private Map<String, InterfaceDefinition> interfaces;
 
-	private List<PropertyDefinition> attributes;
+    private List<String> defaultCapabilities;
+    
+    private Map<String, InterfaceOperationDataDefinition> interfaceOperations;
 
-	// Later
-	private Map<String, InterfaceDefinition> interfaces;
+    public Resource() {
+        super(new ResourceMetadataDefinition());
+        this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.RESOURCE);
+    }
 
-	private List<String> defaultCapabilities;
+    public Resource(ComponentMetadataDefinition componentMetadataDefinition) {
+        super(componentMetadataDefinition);
+        if(this.getComponentMetadataDefinition().getMetadataDataDefinition() == null) {
+            this.getComponentMetadataDefinition().componentMetadataDataDefinition = new ResourceMetadataDataDefinition();
+        }
+        this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.RESOURCE);
+    }
+    /**
+     * Please note that more than one "derivedFrom" resource is not currently
+     * supported by the app. The first list element is always addressed.
+     *
+     * @return
+     */
+    public List<String> getDerivedFrom() {
+        return derivedFrom;
+    }
 
-	private Map<String, InterfaceOperationDataDefinition> interfaceOperations;
+    public void setDerivedFrom(List<String> derivedFrom) {
+        this.derivedFrom = derivedFrom;
+    }
 
-//	private List<AdditionalInformationDefinition> additionalInformation;
+    /**
+     * The derivedList is a chain of derivedFrom. e.g. if resource C is derived
+     * from resource B that is derived from resource A - then A, B is the
+     * "DerivedList" of resource C
+     *
+     * @return
+     */
+    public List<String> getDerivedList() {
+        return derivedList;
+    }
 
-	/**
-	 * Please note that more than one "derivedFrom" resource is not currently
-	 * supported by the app. The first list element is always addressed.
-	 * 
-	 * @return
-	 */
-	public List<String> getDerivedFrom() {
-		return derivedFrom;
-	}
+    public void setDerivedList(List<String> derivedList) {
+        this.derivedList = derivedList;
+    }
 
-	public void setDerivedFrom(List<String> derivedFrom) {
-		this.derivedFrom = derivedFrom;
-	}
+    public List<PropertyDefinition> getProperties() {
+        return properties;
+    }
 
-	/**
-	 * The derivedList is a chain of derivedFrom. e.g. if resource C is derived
-	 * from resource B that is derived from resource A - then A, B is the
-	 * "DerivedList" of resource C
-	 * 
-	 * @return
-	 */
-	public List<String> getDerivedList() {
-		return derivedList;
-	}
+    public void setProperties(List<PropertyDefinition> properties) {
+        this.properties = properties;
+    }
 
-	public void setDerivedList(List<String> derivedList) {
-		this.derivedList = derivedList;
-	}
+    public List<PropertyDefinition> getAttributes() {
+        return attributes;
+    }
 
-	public List<PropertyDefinition> getProperties() {
-		return properties;
-	}
+    public void setAttributes(List<PropertyDefinition> attributes) {
+        this.attributes = attributes;
+    }
 
-	public void setProperties(List<PropertyDefinition> properties) {
-		this.properties = properties;
-	}
+    public Map<String, InterfaceDefinition> getInterfaces() {
+        return interfaces;
+    }
 
-	public List<PropertyDefinition> getAttributes() {
-		return attributes;
-	}
+    public void setInterfaces(Map<String, InterfaceDefinition> interfaces) {
+        this.interfaces = interfaces;
+    }
 
-	public void setAttributes(List<PropertyDefinition> attributes) {
-		this.attributes = attributes;
-	}
+    public Boolean isAbstract() {
+        return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .isAbstract();
+    }
 
-	public Map<String, InterfaceDefinition> getInterfaces() {
-		return interfaces;
-	}
+    public void setAbstract(Boolean isAbstract) {
+        ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .setAbstract(isAbstract);
+    }
 
-	public void setInterfaces(Map<String, InterfaceDefinition> interfaces) {
-		this.interfaces = interfaces;
-	}
+    public List<String> getDefaultCapabilities() {
+        return defaultCapabilities;
+    }
 
-	public Boolean isAbstract() {
-		return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.isAbstract();
-	}
+    public void setDefaultCapabilities(List<String> defaultCapabilities) {
+        this.defaultCapabilities = defaultCapabilities;
+    }
 
-	public void setAbstract(Boolean isAbstract) {
-		((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.setAbstract(isAbstract);
-	}
+    public String getCost() {
+        return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .getCost();
+    }
 
-	public List<String> getDefaultCapabilities() {
-		return defaultCapabilities;
-	}
+    public void setCost(String cost) {
+        ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()).setCost(cost);
+        ;
+    }
 
-	public void setDefaultCapabilities(List<String> defaultCapabilities) {
-		this.defaultCapabilities = defaultCapabilities;
-	}
+    public String getLicenseType() {
+        return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .getLicenseType();
+    }
 
-	public String getCost() {
-		return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.getCost();
-	}
+    public void setLicenseType(String licenseType) {
+        ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .setLicenseType(licenseType);
+    }
 
-	public void setCost(String cost) {
-		((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()).setCost(cost);
-		;
-	}
+    public Map<String, InterfaceOperationDataDefinition> getInterfaceOperations() {
+        return interfaceOperations;
+    }
 
-	public String getLicenseType() {
-		return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.getLicenseType();
-	}
+    public void setInterfaceOperations(Map<String, InterfaceOperationDataDefinition> interfaceOperations) {
+        this.interfaceOperations = interfaceOperations;
+    }
 
-	public void setLicenseType(String licenseType) {
-		((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.setLicenseType(licenseType);
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + super.hashCode();
+        result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
+        result = prime * result + ((defaultCapabilities == null) ? 0 : defaultCapabilities.hashCode());
+        result = prime * result + ((derivedFrom == null) ? 0 : derivedFrom.hashCode());
+        result = prime * result + ((interfaces == null) ? 0 : interfaces.hashCode());
+        result = prime * result + ((properties == null) ? 0 : properties.hashCode());
+        result = prime * result + ((derivedList == null) ? 0 : derivedList.hashCode());
+        return result;
+    }
 
-	public Map<String, InterfaceOperationDataDefinition> getInterfaceOperations() {
-		return interfaceOperations;
-	}
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
 
-	public void setInterfaceOperations(Map<String, InterfaceOperationDataDefinition> interfaceOperations) {
-		this.interfaceOperations = interfaceOperations;
-	}
+        Resource other = (Resource) obj;
+        if (attributes == null) {
+            if (other.attributes != null)
+                return false;
+        } else if (!attributes.equals(other.attributes))
+            return false;
+        if (defaultCapabilities == null) {
+            if (other.defaultCapabilities != null)
+                return false;
+        } else if (!defaultCapabilities.equals(other.defaultCapabilities))
+            return false;
+        if (derivedFrom == null) {
+            if (other.derivedFrom != null)
+                return false;
+        } else if (!derivedFrom.equals(other.derivedFrom))
+            return false;
+        if (derivedList == null) {
+            if (other.derivedList != null)
+                return false;
+        } else if (!derivedList.equals(other.derivedList))
+            return false;
+        if (interfaces == null) {
+            if (other.interfaces != null)
+                return false;
+        } else if (!interfaces.equals(other.interfaces))
+            return false;
+        if (properties == null) {
+            if (other.properties != null)
+                return false;
+        } else if (!properties.equals(other.properties))
+            return false;
 
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + super.hashCode();
+        return super.equals(obj);
+    }
 
-		result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
-		// result = prime * result + ((capabilities == null) ? 0 :
-		// capabilities.hashCode());
-		result = prime * result + ((defaultCapabilities == null) ? 0 : defaultCapabilities.hashCode());
-		result = prime * result + ((derivedFrom == null) ? 0 : derivedFrom.hashCode());
-		result = prime * result + ((interfaces == null) ? 0 : interfaces.hashCode());
-		result = prime * result + ((properties == null) ? 0 : properties.hashCode());
-		result = prime * result + ((derivedList == null) ? 0 : derivedList.hashCode());
-		result = prime * result + ((interfaceOperations == null) ? 0 : interfaceOperations.hashCode());
-		// result = prime * result + ((requirements == null) ? 0 :
-		// requirements.hashCode());
-		return result;
-	}
+    @Override
+    public String toString() {
+        return "Resource [derivedFrom=" + derivedFrom + ", properties=" + properties + ", attributes=" + attributes
+                + ", interfaces=" + interfaces
+                + ", defaultCapabilities=" + defaultCapabilities + ", additionalInformation=" + additionalInformation
+                + "Metadata [" + getComponentMetadataDefinition().getMetadataDataDefinition().toString() + "]";
+    }
 
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
+    public String getToscaResourceName() {
+        return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .getToscaResourceName();
+    }
 
-		Resource other = (Resource) obj;
-		if (attributes == null) {
-			if (other.attributes != null)
-				return false;
-		} else if (!attributes.equals(other.attributes))
-			return false;
-		if (defaultCapabilities == null) {
-			if (other.defaultCapabilities != null)
-				return false;
-		} else if (!defaultCapabilities.equals(other.defaultCapabilities))
-			return false;
-		if (derivedFrom == null) {
-			if (other.derivedFrom != null)
-				return false;
-		} else if (!derivedFrom.equals(other.derivedFrom))
-			return false;
-		if (derivedList == null) {
-			if (other.derivedList != null)
-				return false;
-		} else if (!derivedList.equals(other.derivedList))
-			return false;
-		if (interfaces == null) {
-			if (other.interfaces != null)
-				return false;
-		} else if (!interfaces.equals(other.interfaces))
-			return false;
-		if (properties == null) {
-			if (other.properties != null)
-				return false;
-		} else if (!properties.equals(other.properties))
-			return false;
-		if (interfaceOperations == null) {
-			if (other.interfaceOperations != null)
-				return false;
-		} else if (!interfaceOperations.equals(other.interfaceOperations))
-			return false;
-		return super.equals(obj);
-	}
+    public void setToscaResourceName(String toscaResourceName) {
+        ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .setToscaResourceName(toscaResourceName);
+    }
 
-	@Override
-	public String toString() {
-		return "Resource [derivedFrom=" + derivedFrom + ", properties=" + properties + ", attributes=" + attributes
-				+ ", interfaces=" + interfaces
-				// + ", capabilities=" + capabilities + ", requirements=" +
-				// requirements
-				+ ", defaultCapabilities=" + defaultCapabilities + ", additionalInformation=" + additionalInformation
-			+ ", interfaceOperations=" + interfaceOperations
-				+ "Metadata [" + getComponentMetadataDefinition().getMetadataDataDefinition().toString() + "]";
-	}
+    public ResourceTypeEnum getResourceType() {
+        return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .getResourceType();
+    }
 
-	public String getToscaResourceName() {
-		return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.getToscaResourceName();
-	}
+    public void setResourceType(ResourceTypeEnum resourceType) {
+        ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .setResourceType(resourceType);
+    }
 
-	public void setToscaResourceName(String toscaResourceName) {
-		((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.setToscaResourceName(toscaResourceName);
-	}
+    public void setVendorName(String vendorName) {
+        ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .setVendorName(vendorName);
+    }
 
-	public ResourceTypeEnum getResourceType() {
-		return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.getResourceType();
-	}
+    public void setVendorRelease(String vendorRelease) {
+        ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .setVendorRelease(vendorRelease);
+    }
 
-	public void setResourceType(ResourceTypeEnum resourceType) {
-		((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.setResourceType(resourceType);
-	}
+    public void setResourceVendorModelNumber(String resourceVendorModelNumber){
+        ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()).
+        setResourceVendorModelNumber(resourceVendorModelNumber);
+    }
 
-	public void setVendorName(String vendorName) {
-		((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.setVendorName(vendorName);
-	}
+    public String getVendorName() {
+        return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .getVendorName();
+    }
 
-	public void setVendorRelease(String vendorRelease) {
-		((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.setVendorRelease(vendorRelease);
-	}
-	
-	public void setResourceVendorModelNumber(String resourceVendorModelNumber){
-		((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()).
-		setResourceVendorModelNumber(resourceVendorModelNumber);
-	}
+    public String getVendorRelease() {
+        return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .getVendorRelease();
+    }
 
-	public String getVendorName() {
-		return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.getVendorName();
-	}
+    public String getResourceVendorModelNumber(){
+        return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
+                .getResourceVendorModelNumber();
+    }
 
-	public String getVendorRelease() {
-		return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.getVendorRelease();
-	}
-	
-	public String getResourceVendorModelNumber(){
-		return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition())
-				.getResourceVendorModelNumber();
-	}
-	
-	@Override
-	public String fetchGenericTypeToscaNameFromConfig(){
-		String result = super.fetchGenericTypeToscaNameFromConfig();
-		if(null == result)
-			result = ConfigurationManager.getConfigurationManager().getConfiguration().getGenericAssetNodeTypes().get(ResourceTypeEnum.VFC.getValue());
-		return result;
-	}
-	
-	@Override
-	public String assetType(){
-		return this.getResourceType().name();
-	}
-	
-	@Override
-	public boolean shouldGenerateInputs(){
-		//TODO add complex VFC condition when supported
-		return !(this.getResourceType().isAtomicType());
-	}
-	
-	@Override
-	public boolean deriveFromGeneric(){	
-		return this.shouldGenerateInputs() || (derivedFrom != null && derivedFrom.contains(fetchGenericTypeToscaNameFromConfig()));
-	}
+    @Override
+    public String fetchGenericTypeToscaNameFromConfig(){
+        String result = super.fetchGenericTypeToscaNameFromConfig();
+        if(null == result)
+            result = ConfigurationManager.getConfigurationManager().getConfiguration().getGenericAssetNodeTypes().get(ResourceTypeEnum.VFC.getValue());
+        return result;
+    }
 
-	public Map<String, List<RequirementCapabilityRelDef>> groupRelationsByInstanceName(Resource resource) {
-		Map<String, List<RequirementCapabilityRelDef>> relationsByInstanceId = MapUtil.groupListBy(resource.getComponentInstancesRelations(), RequirementCapabilityRelDef::getFromNode);
-		return MapUtil.convertMapKeys(relationsByInstanceId, (instId) -> getInstanceNameFromInstanceId(resource, instId));
-	}
+    @Override
+    public String assetType(){
+        return this.getResourceType().name();
+    }
 
-	private String getInstanceNameFromInstanceId(Resource resource, String instId) {
+    @Override
+    public boolean shouldGenerateInputs(){
+        //TODO add complex VFC condition when supported
+        return !(this.getResourceType().isAtomicType());
+    }
+
+    @Override
+    public boolean deriveFromGeneric(){
+        return this.shouldGenerateInputs() || (derivedFrom != null && derivedFrom.contains(fetchGenericTypeToscaNameFromConfig()));
+    }
+
+    public Map<String, List<RequirementCapabilityRelDef>> groupRelationsByInstanceName(Resource resource) {
+        Map<String, List<RequirementCapabilityRelDef>> relationsByInstanceId = MapUtil.groupListBy(resource.getComponentInstancesRelations(), RequirementCapabilityRelDef::getFromNode);
+        return MapUtil.convertMapKeys(relationsByInstanceId, (instId) -> getInstanceNameFromInstanceId(resource, instId));
+    }
+
+    private String getInstanceNameFromInstanceId(Resource resource, String instId) {
 		Optional<ComponentInstance> componentInstanceById = resource.getComponentInstanceById(instId);
 		return componentInstanceById.isPresent() ? componentInstanceById.get().getName() : null;
-	}
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.java
index 75dfdff..8c1f336 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.java
@@ -22,27 +22,27 @@
 
 public class ResourceInstanceHeatParameter extends HeatParameterDefinition {
 
-	private String valueUniqueId;
+    private String valueUniqueId;
 
-	public ResourceInstanceHeatParameter() {
-		super();
-	}
+    public ResourceInstanceHeatParameter() {
+        super();
+    }
 
-	public ResourceInstanceHeatParameter(HeatParameterDefinition heatParameterDefinition, String valueId) {
-		super(heatParameterDefinition);
-		valueUniqueId = valueId;
-	}
+    public ResourceInstanceHeatParameter(HeatParameterDefinition heatParameterDefinition, String valueId) {
+        super(heatParameterDefinition);
+        valueUniqueId = valueId;
+    }
 
-	public String getValueUniqueId() {
-		return valueUniqueId;
-	}
+    public String getValueUniqueId() {
+        return valueUniqueId;
+    }
 
-	public void setValueUniqueId(String valueUniqueId) {
-		this.valueUniqueId = valueUniqueId;
-	}
+    public void setValueUniqueId(String valueUniqueId) {
+        this.valueUniqueId = valueUniqueId;
+    }
 
-	@Override
-	public String toString() {
-		return "ResourceInstanceHeatParameter [ " + super.toString() + " , valueUniqueId = " + valueUniqueId + " ]";
-	}
+    @Override
+    public String toString() {
+        return "ResourceInstanceHeatParameter [ " + super.toString() + " , valueUniqueId = " + valueUniqueId + " ]";
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.java
index 2448191..c049bdc 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.java
@@ -24,14 +24,14 @@
 
 public class ResourceMetadataDefinition extends ComponentMetadataDefinition {
 
-	public ResourceMetadataDefinition() {
-		super();
-		this.componentMetadataDataDefinition = new ResourceMetadataDataDefinition();
-	}
+    public ResourceMetadataDefinition() {
+        super();
+        this.componentMetadataDataDefinition = new ResourceMetadataDataDefinition();
+    }
 
-	public ResourceMetadataDefinition(ResourceMetadataDataDefinition other) {
-		super(other);
+    public ResourceMetadataDefinition(ResourceMetadataDataDefinition other) {
+        super(other);
 
-	}
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.java
index cce4820..978ac5f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.java
@@ -27,16 +27,16 @@
  * Schema allows to create new types that can be used along TOSCA definitions.
  */
 public class Schema {
-	private String derivedFrom;
-	private List<PropertyConstraint> constraints;
-	private Map<String, PropertyDefinition> properties;
-	private PropertyDefinition property;
+    private String derivedFrom;
+    private List<PropertyConstraint> constraints;
+    private Map<String, PropertyDefinition> properties;
+    private PropertyDefinition property;
 
-	public PropertyDefinition getProperty() {
-		return property;
-	}
+    public PropertyDefinition getProperty() {
+        return property;
+    }
 
-	public void setProperty(PropertyDefinition property) {
-		this.property = property;
-	}
+    public void setProperty(PropertyDefinition property) {
+        this.property = property;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java
index 2590833..823abab 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java
@@ -20,24 +20,24 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.HashMap;
-import java.util.Map;
-
+import org.apache.commons.lang.StringUtils;
 import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition;
 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.InstantiationTypes;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
 
+import java.util.HashMap;
+import java.util.Map;
+
 public class Service extends Component {
 
-	private static final long serialVersionUID = -8819935942700578059L;
-
-	public Service() {
-		super(new ServiceMetadataDefinition());
-		this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.SERVICE);
-		this.setToscaType(ToscaElementTypeEnum.TopologyTemplate.getValue());
-	}
+    public Service() {
+        super(new ServiceMetadataDefinition());
+        this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.SERVICE);
+        this.setToscaType(ToscaElementTypeEnum.TOPOLOGY_TEMPLATE.getValue());
+    }
 
 	public Service(ComponentMetadataDefinition serviceMetadataDefinition) {
 		super(serviceMetadataDefinition);
@@ -45,7 +45,7 @@
 		if(metadataDataDefinition != null) {
 			metadataDataDefinition.setComponentType(ComponentTypeEnum.SERVICE);
 		}
-		this.setToscaType(ToscaElementTypeEnum.TopologyTemplate.getValue());
+		this.setToscaType(ToscaElementTypeEnum.TOPOLOGY_TEMPLATE.getValue());
 	}
 
 	private Map<String, ArtifactDefinition> serviceApiArtifacts;
@@ -113,7 +113,7 @@
 		return getServiceMetadataDefinition().getNamingPolicy();
 	}
 
-	public String getEnvironmentContext() { return getServiceMetadataDefinition().getEnvironmentContext();  }
+    public String getEnvironmentContext() { return getServiceMetadataDefinition().getEnvironmentContext();  }
 
 	public void setEnvironmentContext(String environmentContext) {
 		getServiceMetadataDefinition().setEnvironmentContext(environmentContext);
@@ -135,11 +135,26 @@
 		return getServiceMetadataDefinition().getServiceRole();
 	}
 
+	public void setInstantiationType(String instantiationType){
+		getServiceMetadataDefinition().setInstantiationType(instantiationType);
+	}
+
+	public String getInstantiationType(){
+		return getServiceMetadataDefinition().getInstantiationType();
+	}
+
 	private ServiceMetadataDataDefinition getServiceMetadataDefinition() {
 		return (ServiceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition();
 	}
 
 
+	public void validateAndSetInstantiationType() { 
+		if (this.getInstantiationType() == StringUtils.EMPTY) {
+			this.setInstantiationType(InstantiationTypes.A_LA_CARTE.getValue());
+		}
+	}
+
+
 	@Override
 	public String toString() {
 		return "Service [componentMetadataDefinition=" + getComponentMetadataDefinition()
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.java
index 21b2e43..42111e0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.java
@@ -24,13 +24,13 @@
 
 public class ServiceMetadataDefinition extends ComponentMetadataDefinition {
 
-	public ServiceMetadataDefinition() {
-		super();
-		this.componentMetadataDataDefinition = new ServiceMetadataDataDefinition();
-	}
+    public ServiceMetadataDefinition() {
+        super();
+        this.componentMetadataDataDefinition = new ServiceMetadataDataDefinition();
+    }
 
-	public ServiceMetadataDefinition(ServiceMetadataDataDefinition component) {
-		super(component);
-	}
+    public ServiceMetadataDefinition(ServiceMetadataDataDefinition component) {
+        super(component);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.java
index f3edfe2..045294e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.java
@@ -22,44 +22,44 @@
 
 public class Tag {
 
-	private String name;
+    private String name;
 
-	public String getName() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((name == null) ? 0 : name.hashCode());
-		return result;
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        return result;
+    }
 
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj) {
-			return true;
-		}
-		if (obj == null) {
-			return false;
-		}
-		if (getClass() != obj.getClass()) {
-			return false;
-		}
-		Tag other = (Tag) obj;
-		if (name == null) {
-			if (other.getClass() != null) {
-				return false;
-			}
-		} else if (!name.equals(other.getName())) {
-			return false;
-		}
-		return true;
-	}
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        Tag other = (Tag) obj;
+        if (name == null) {
+            if (other.getClass() != null) {
+                return false;
+            }
+        } else if (!name.equals(other.getName())) {
+            return false;
+        }
+        return true;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.java
index 8da4c11..1237ade 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.java
@@ -20,72 +20,56 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.io.Serializable;
 import java.util.List;
 
-public class TargetCapabilityRelDef implements Serializable {
+public class TargetCapabilityRelDef {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -7571489368200736413L;
+    private String uid;
+    private String toNode;
 
-	private String uid;
-	private String toNode;
+    private List<CapabilityRequirementRelationship> relationships;
 
-	private List<CapabilityRequirementRelationship> relationships;
+    public TargetCapabilityRelDef() {
+        super();
+    }
 
-	public TargetCapabilityRelDef() {
-		super();
-	}
+    public TargetCapabilityRelDef(String toNode, List<CapabilityRequirementRelationship> relationships) {
+        this.toNode = toNode;
+        this.relationships = relationships;
+    }
 
-	public TargetCapabilityRelDef(String toNode, List<CapabilityRequirementRelationship> relationships) {
-		super();
-		this.toNode = toNode;
-		this.relationships = relationships;
-	}
+    public String getToNode() {
+        return toNode;
+    }
 
-	public String getToNode() {
-		return toNode;
-	}
+    public void setToNode(String toNode) {
+        this.toNode = toNode;
+    }
 
-	public void setToNode(String toNode) {
-		this.toNode = toNode;
-	}
+    public List<CapabilityRequirementRelationship> getRelationships() {
+        return relationships;
+    }
 
-	// public String getCapabilityOwnerId() {
-	// return capabilityOwnerId;
-	// }
-	//
-	// public void setCapabilityOwnerId(String capabilityOwnerId) {
-	// this.capabilityOwnerId = capabilityOwnerId;
-	// }
+    public CapabilityRequirementRelationship resolveSingleRelationship() {//currently only single relationship is supported
+        return relationships == null || relationships.isEmpty() ? null : relationships.get(0);
+    }
 
-	public List<CapabilityRequirementRelationship> getRelationships() {
-		return relationships;
-	}
+    public String getUid() {
+        return uid;
+    }
 
-	public CapabilityRequirementRelationship resolveSingleRelationship() {//currently only single relationship is supported
-		return relationships == null || relationships.isEmpty() ? null : relationships.get(0);
-	}
+    public void setUid(String uid) {
+        this.uid = uid;
+    }
 
-	public String getUid() {
-		return uid;
-	}
+    public void setRelationships(List<CapabilityRequirementRelationship> relationships) {
+        this.relationships = relationships;
+    }
 
-	public void setUid(String uid) {
-		this.uid = uid;
-	}
-
-	public void setRelationships(List<CapabilityRequirementRelationship> relationships) {
-		this.relationships = relationships;
-	}
-
-	@Override
-	public String toString() {
-		return "TargetCapabilityRelDef [ toNode=" + toNode
-		// + ", capabilityOwnerId=" + capabilityOwnerId
-				+ ", relationships=" + relationships + "]";
-	}
+    @Override
+    public String toString() {
+        return "TargetCapabilityRelDef [ toNode=" + toNode
+                + ", relationships=" + relationships + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.java
index d163304..7d15799 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.java
@@ -23,36 +23,36 @@
 import java.util.List;
 
 public class UploadCapInfo extends UploadInfo {
-	/**
-	 * specify the node type(Optional by tosca)
-	 */
-	private List<String> validSourceTypes;
+    /**
+     * specify the node type(Optional by tosca)
+     */
+    private List<String> validSourceTypes;
 
-	private List<UploadPropInfo> properties;
+    private List<UploadPropInfo> properties;
 
-	private String node;
+    private String node;
 
-	public String getNode() {
-		return node;
-	}
+    public String getNode() {
+        return node;
+    }
 
-	public void setNode(String node) {
-		this.node = node;
-	}
+    public void setNode(String node) {
+        this.node = node;
+    }
 
-	public List<String> getValidSourceTypes() {
-		return validSourceTypes;
-	}
+    public List<String> getValidSourceTypes() {
+        return validSourceTypes;
+    }
 
-	public void setValidSourceTypes(List<String> validSourceTypes) {
-		this.validSourceTypes = validSourceTypes;
-	}
+    public void setValidSourceTypes(List<String> validSourceTypes) {
+        this.validSourceTypes = validSourceTypes;
+    }
 
-	public List<UploadPropInfo> getProperties() {
-		return properties;
-	}
+    public List<UploadPropInfo> getProperties() {
+        return properties;
+    }
 
-	public void setProperties(List<UploadPropInfo> properties) {
-		this.properties = properties;
-	}
+    public void setProperties(List<UploadPropInfo> properties) {
+        this.properties = properties;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java
index eb70778..3454fd7 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java
@@ -24,68 +24,68 @@
 import java.util.Map;
 
 public class UploadComponentInstanceInfo {
-	private String name;
-	private String type;
-	private Map<String, List<UploadCapInfo>> capabilities;
-	private Map<String, List<UploadReqInfo>> requirements;
-	private Map<String, List<UploadPropInfo>> properties;
-	private Map<String, String> capabilitiesNamesToUpdate;
-	private Map<String, String> requirementsNamesToUpdate;
+    private String name;
+    private String type;
+    private Map<String, List<UploadCapInfo>> capabilities;
+    private Map<String, List<UploadReqInfo>> requirements;
+    private Map<String, List<UploadPropInfo>> properties;
+    private Map<String, String> capabilitiesNamesToUpdate;
+    private Map<String, String> requirementsNamesToUpdate;
 
-	public Map<String, List<UploadPropInfo>> getProperties() {
-		return properties;
-	}
+    public Map<String, List<UploadPropInfo>> getProperties() {
+        return properties;
+    }
 
-	public void setProperties(Map<String, List<UploadPropInfo>> properties) {
-		this.properties = properties;
-	}
+    public void setProperties(Map<String, List<UploadPropInfo>> properties) {
+        this.properties = properties;
+    }
 
-	public String getName() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
-	public String getType() {
-		return type;
-	}
+    public String getType() {
+        return type;
+    }
 
-	public void setType(String type) {
-		this.type = type;
-	}
+    public void setType(String type) {
+        this.type = type;
+    }
 
-	public Map<String, List<UploadCapInfo>> getCapabilities() {
-		return capabilities;
-	}
+    public Map<String, List<UploadCapInfo>> getCapabilities() {
+        return capabilities;
+    }
 
-	public void setCapabilities(Map<String, List<UploadCapInfo>> capabilities) {
-		this.capabilities = capabilities;
-	}
+    public void setCapabilities(Map<String, List<UploadCapInfo>> capabilities) {
+        this.capabilities = capabilities;
+    }
 
-	public Map<String, List<UploadReqInfo>> getRequirements() {
-		return requirements;
-	}
+    public Map<String, List<UploadReqInfo>> getRequirements() {
+        return requirements;
+    }
 
-	public void setRequirements(Map<String, List<UploadReqInfo>> requirements) {
-		this.requirements = requirements;
-	}
+    public void setRequirements(Map<String, List<UploadReqInfo>> requirements) {
+        this.requirements = requirements;
+    }
 
-	public Map<String, String> getCapabilitiesNamesToUpdate() {
-		return capabilitiesNamesToUpdate;
-	}
+    public Map<String, String> getCapabilitiesNamesToUpdate() {
+        return capabilitiesNamesToUpdate;
+    }
 
-	public void setCapabilitiesNamesToUpdate(Map<String, String> capabilitiesNamesToUpdate) {
-		this.capabilitiesNamesToUpdate = capabilitiesNamesToUpdate;
-	}
+    public void setCapabilitiesNamesToUpdate(Map<String, String> capabilitiesNamesToUpdate) {
+        this.capabilitiesNamesToUpdate = capabilitiesNamesToUpdate;
+    }
 
-	public Map<String, String> getRequirementsNamesToUpdate() {
-		return requirementsNamesToUpdate;
-	}
+    public Map<String, String> getRequirementsNamesToUpdate() {
+        return requirementsNamesToUpdate;
+    }
 
-	public void setRequirementsNamesToUpdate(Map<String, String> requirementsNamesToUpdate) {
-		this.requirementsNamesToUpdate = requirementsNamesToUpdate;
-	}
+    public void setRequirementsNamesToUpdate(Map<String, String> requirementsNamesToUpdate) {
+        this.requirementsNamesToUpdate = requirementsNamesToUpdate;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.java
index 52a7ec0..d642737 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.java
@@ -22,34 +22,34 @@
 
 public abstract class UploadInfo {
 
-	private String key;
-	
-	private String type;
+    private String key;
 
-	private String name;
+    private String type;
 
-	public String getKey() {
-		return key;
-	}
+    private String name;
 
-	public void setKey(String key) {
-		this.key = key;
-	}
+    public String getKey() {
+        return key;
+    }
 
-	public String getType() {
-		return type;
-	}
+    public void setKey(String key) {
+        this.key = key;
+    }
 
-	public void setType(String type) {
-		this.type = type;
-	}
+    public String getType() {
+        return type;
+    }
 
-	public String getName() {
-		return name;
-	}
+    public void setType(String type) {
+        this.type = type;
+    }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java
index 2683407..536e251 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java
@@ -20,51 +20,55 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
 
+import java.util.ArrayList;
+import java.util.List;
+
 
 public class UploadPropInfo extends UploadInfo {
 
-	private Object value;
+    private Object value;
 
-	private String description;
+    private String description;
 
-	private boolean password;
+    private boolean password;
 
-	private List<GetInputValueDataDefinition> get_input;
+    private List<GetInputValueDataDefinition> get_input;
 
-	public List<GetInputValueDataDefinition> getGet_input() {
-		return get_input;
-	}
+    public List<GetInputValueDataDefinition> getGet_input() {
+        if (get_input == null) {
+            get_input = new ArrayList<>();
+        }
+        return get_input;
+    }
 
-	public void setGet_input(List<GetInputValueDataDefinition> get_input) {
-		this.get_input = get_input;
-	}
+    public void setGet_input(List<GetInputValueDataDefinition> get_input) {
+        this.get_input = get_input;
+    }
 
-	public Object getValue() {
-		return value;
-	}
+    public Object getValue() {
+        return value;
+    }
 
-	public void setValue(Object value) {
-		this.value = value;
-	}
+    public void setValue(Object value) {
+        this.value = value;
+    }
 
-	public String getDescription() {
-		return description;
-	}
+    public String getDescription() {
+        return description;
+    }
 
-	public void setDescription(String description) {
-		this.description = description;
-	}
+    public void setDescription(String description) {
+        this.description = description;
+    }
 
-	public boolean isPassword() {
-		return password;
-	}
+    public boolean isPassword() {
+        return password;
+    }
 
-	public void setPassword(boolean password) {
-		this.password = password;
-	}
+    public void setPassword(boolean password) {
+        this.password = password;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.java
index e2a6c3c..47f8f1c 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.java
@@ -21,28 +21,28 @@
 package org.openecomp.sdc.be.model;
 
 public class UploadReqInfo extends UploadInfo {
-	/**
-	 * specify the node type(Optional by tosca)
-	 */
+    /**
+     * specify the node type(Optional by tosca)
+     */
 
-	private String capabilityName;
+    private String capabilityName;
 
-	private String node;
+    private String node;
 
-	public String getCapabilityName() {
-		return capabilityName;
-	}
+    public String getCapabilityName() {
+        return capabilityName;
+    }
 
-	public void setCapabilityName(String capabilityName) {
-		this.capabilityName = capabilityName;
-	}
+    public void setCapabilityName(String capabilityName) {
+        this.capabilityName = capabilityName;
+    }
 
-	public String getNode() {
-		return node;
-	}
+    public String getNode() {
+        return node;
+    }
 
-	public void setNode(String node) {
-		this.node = node;
-	}
+    public void setNode(String node) {
+        this.node = node;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java
index 36ac871..ecc3403 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java
@@ -20,312 +20,312 @@
 
 package org.openecomp.sdc.be.model;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
 import org.openecomp.sdc.common.api.UploadArtifactInfo;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class UploadResourceInfo {
 
-	private String payloadData;
-	private String payloadName;
-	private String description;
-	private List<String> tags;
-	private List<CategoryDefinition> categories;
+    private String payloadData;
+    private String payloadName;
+    private String description;
+    private List<String> tags;
+    private List<CategoryDefinition> categories;
 
-	private List<UploadArtifactInfo> artifactList;
-	private String contactId, name, resourceIconPath, icon, vendorName, vendorRelease, resourceVendorModelNumber;
+    private List<UploadArtifactInfo> artifactList;
+    private String contactId, name, resourceIconPath, icon, vendorName, vendorRelease, resourceVendorModelNumber;
 
-	private String resourceType = "VFC";
+    private String resourceType = "VFC";
 
-	public UploadResourceInfo(String payload, String payloadName, String description, String category,
-							  List<String> tags, List<UploadArtifactInfo> artifactsList) {
-		super();
-		this.payloadData = payload;
-		this.payloadName = payloadName;
-		this.description = description;
-		this.tags = tags;
-		this.artifactList = artifactsList;
-		if (category != null) {
-			String[] arr = category.split("/");
-			if (arr.length >= 2) {
-				categories = new ArrayList<>();
-				CategoryDefinition catDef = new CategoryDefinition();
-				catDef.setName(arr[0]);
-				SubCategoryDefinition subCat = new SubCategoryDefinition();
-				subCat.setName(arr[1]);
-				catDef.addSubCategory(subCat);
-				categories.add(catDef);
-			}
-		}
-	}
+    public UploadResourceInfo(String payload, String payloadName, String description, String category,
+                              List<String> tags, List<UploadArtifactInfo> artifactsList) {
+        super();
+        this.payloadData = payload;
+        this.payloadName = payloadName;
+        this.description = description;
+        this.tags = tags;
+        this.artifactList = artifactsList;
+        if (category != null) {
+            String[] arr = category.split("/");
+            if (arr.length >= 2) {
+                categories = new ArrayList<>();
+                CategoryDefinition catDef = new CategoryDefinition();
+                catDef.setName(arr[0]);
+                SubCategoryDefinition subCat = new SubCategoryDefinition();
+                subCat.setName(arr[1]);
+                catDef.addSubCategory(subCat);
+                categories.add(catDef);
+            }
+        }
+    }
 
-	public UploadResourceInfo() {
-	}
+    public UploadResourceInfo() {
+    }
 
 
-	public String getPayloadData() {
-		return payloadData;
-	}
+    public String getPayloadData() {
+        return payloadData;
+    }
 
-	public void setPayloadData(String payload) {
-		this.payloadData = payload;
-	}
+    public void setPayloadData(String payload) {
+        this.payloadData = payload;
+    }
 
-	public String getPayloadName() {
-		return payloadName;
-	}
+    public String getPayloadName() {
+        return payloadName;
+    }
 
-	public void setPayloadName(String payloadName) {
-		this.payloadName = payloadName;
-	}
+    public void setPayloadName(String payloadName) {
+        this.payloadName = payloadName;
+    }
 
-	public String getDescription() {
-		return description;
-	}
+    public String getDescription() {
+        return description;
+    }
 
-	public void setDescription(String description) {
-		this.description = description;
-	}
+    public void setDescription(String description) {
+        this.description = description;
+    }
 
-	public List<String> getTags() {
-		return tags;
-	}
+    public List<String> getTags() {
+        return tags;
+    }
 
-	public void setTags(List<String> tags) {
-		this.tags = tags;
-	}
+    public void setTags(List<String> tags) {
+        this.tags = tags;
+    }
 
-	public List<UploadArtifactInfo> getArtifactList() {
-		return artifactList;
-	}
+    public List<UploadArtifactInfo> getArtifactList() {
+        return artifactList;
+    }
 
-	public void setArtifactList(List<UploadArtifactInfo> artifactsList) {
-		this.artifactList = artifactsList;
-	}
+    public void setArtifactList(List<UploadArtifactInfo> artifactsList) {
+        this.artifactList = artifactsList;
+    }
 
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((artifactList == null) ? 0 : artifactList.hashCode());
-		result = prime * result + ((contactId == null) ? 0 : contactId.hashCode());
-		result = prime * result + ((description == null) ? 0 : description.hashCode());
-		result = prime * result + ((icon == null) ? 0 : icon.hashCode());
-		result = prime * result + ((payloadData == null) ? 0 : payloadData.hashCode());
-		result = prime * result + ((payloadName == null) ? 0 : payloadName.hashCode());
-		result = prime * result + ((resourceIconPath == null) ? 0 : resourceIconPath.hashCode());
-		result = prime * result + ((name == null) ? 0 : name.hashCode());
-		result = prime * result + ((tags == null) ? 0 : tags.hashCode());
-		result = prime * result + ((vendorName == null) ? 0 : vendorName.hashCode());
-		result = prime * result + ((vendorRelease == null) ? 0 : vendorRelease.hashCode());
-		result = prime * result + ((resourceVendorModelNumber == null) ? 0 : resourceVendorModelNumber.hashCode());
-		return result;
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((artifactList == null) ? 0 : artifactList.hashCode());
+        result = prime * result + ((contactId == null) ? 0 : contactId.hashCode());
+        result = prime * result + ((description == null) ? 0 : description.hashCode());
+        result = prime * result + ((icon == null) ? 0 : icon.hashCode());
+        result = prime * result + ((payloadData == null) ? 0 : payloadData.hashCode());
+        result = prime * result + ((payloadName == null) ? 0 : payloadName.hashCode());
+        result = prime * result + ((resourceIconPath == null) ? 0 : resourceIconPath.hashCode());
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((tags == null) ? 0 : tags.hashCode());
+        result = prime * result + ((vendorName == null) ? 0 : vendorName.hashCode());
+        result = prime * result + ((vendorRelease == null) ? 0 : vendorRelease.hashCode());
+        result = prime * result + ((resourceVendorModelNumber == null) ? 0 : resourceVendorModelNumber.hashCode());
+        return result;
+    }
 
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj) {
-			return true;
-		}
-		if (obj == null) {
-			return false;
-		}
-		if (getClass() != obj.getClass()) {
-			return false;
-		}
-		UploadResourceInfo other = (UploadResourceInfo) obj;
-		if (artifactList == null) {
-			if (other.artifactList != null) {
-				return false;
-			}
-		} else if (!artifactList.equals(other.artifactList)) {
-			return false;
-		}
-		if (contactId == null) {
-			if (other.contactId != null) {
-				return false;
-			}
-		} else if (!contactId.equals(other.contactId)) {
-			return false;
-		}
-		if (description == null) {
-			if (other.description != null) {
-				return false;
-			}
-		} else if (!description.equals(other.description)) {
-			return false;
-		}
-		if (icon == null) {
-			if (other.icon != null) {
-				return false;
-			}
-		} else if (!icon.equals(other.icon)) {
-			return false;
-		}
-		if (payloadData == null) {
-			if (other.payloadData != null) {
-				return false;
-			}
-		} else if (!payloadData.equals(other.payloadData)) {
-			return false;
-		}
-		if (payloadName == null) {
-			if (other.payloadName != null) {
-				return false;
-			}
-		} else if (!payloadName.equals(other.payloadName)) {
-			return false;
-		}
-		if (resourceIconPath == null) {
-			if (other.resourceIconPath != null) {
-				return false;
-			}
-		} else if (!resourceIconPath.equals(other.resourceIconPath)) {
-			return false;
-		}
-		if (name == null) {
-			if (other.name != null) {
-				return false;
-			}
-		} else if (!name.equals(other.name)) {
-			return false;
-		}
-		if (tags == null) {
-			if (other.tags != null) {
-				return false;
-			}
-		} else if (!tags.equals(other.tags)) {
-			return false;
-		}
-		if (vendorName == null) {
-			if (other.vendorName != null) {
-				return false;
-			}
-		} else if (!vendorName.equals(other.vendorName)) {
-			return false;
-		}
-		if (resourceVendorModelNumber == null) {
-			if (other.resourceVendorModelNumber != null) {
-				return false;
-			}
-		} else if (!resourceVendorModelNumber.equals(other.resourceVendorModelNumber)) {
-			return false;
-		}
-		if (vendorRelease == null) {
-			if (other.vendorRelease != null) {
-				return false;
-			}
-		} else if (!vendorRelease.equals(other.vendorRelease)) {
-			return false;
-		}
-		return true;
-	}
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        UploadResourceInfo other = (UploadResourceInfo) obj;
+        if (artifactList == null) {
+            if (other.artifactList != null) {
+                return false;
+            }
+        } else if (!artifactList.equals(other.artifactList)) {
+            return false;
+        }
+        if (contactId == null) {
+            if (other.contactId != null) {
+                return false;
+            }
+        } else if (!contactId.equals(other.contactId)) {
+            return false;
+        }
+        if (description == null) {
+            if (other.description != null) {
+                return false;
+            }
+        } else if (!description.equals(other.description)) {
+            return false;
+        }
+        if (icon == null) {
+            if (other.icon != null) {
+                return false;
+            }
+        } else if (!icon.equals(other.icon)) {
+            return false;
+        }
+        if (payloadData == null) {
+            if (other.payloadData != null) {
+                return false;
+            }
+        } else if (!payloadData.equals(other.payloadData)) {
+            return false;
+        }
+        if (payloadName == null) {
+            if (other.payloadName != null) {
+                return false;
+            }
+        } else if (!payloadName.equals(other.payloadName)) {
+            return false;
+        }
+        if (resourceIconPath == null) {
+            if (other.resourceIconPath != null) {
+                return false;
+            }
+        } else if (!resourceIconPath.equals(other.resourceIconPath)) {
+            return false;
+        }
+        if (name == null) {
+            if (other.name != null) {
+                return false;
+            }
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        if (tags == null) {
+            if (other.tags != null) {
+                return false;
+            }
+        } else if (!tags.equals(other.tags)) {
+            return false;
+        }
+        if (vendorName == null) {
+            if (other.vendorName != null) {
+                return false;
+            }
+        } else if (!vendorName.equals(other.vendorName)) {
+            return false;
+        }
+        if (resourceVendorModelNumber == null) {
+            if (other.resourceVendorModelNumber != null) {
+                return false;
+            }
+        } else if (!resourceVendorModelNumber.equals(other.resourceVendorModelNumber)) {
+            return false;
+        }
+        if (vendorRelease == null) {
+            if (other.vendorRelease != null) {
+                return false;
+            }
+        } else if (!vendorRelease.equals(other.vendorRelease)) {
+            return false;
+        }
+        return true;
+    }
 
-	public String getContactId() {
-		return contactId;
-	}
+    public String getContactId() {
+        return contactId;
+    }
 
-	public void setContactId(String userId) {
-		this.contactId = userId;
-	}
+    public void setContactId(String userId) {
+        this.contactId = userId;
+    }
 
-	public String getName() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setName(String resourceName) {
-		this.name = resourceName;
-	}
+    public void setName(String resourceName) {
+        this.name = resourceName;
+    }
 
-	// Icon when using UI import otherwise resourceIconPath
-	public String getResourceIconPath() {
-		return (resourceIconPath != null) ? resourceIconPath : icon;
-	}
+    // Icon when using UI import otherwise resourceIconPath
+    public String getResourceIconPath() {
+        return (resourceIconPath != null) ? resourceIconPath : icon;
+    }
 
-	public void setResourceIconPath(String resourceIconPath) {
-		this.resourceIconPath = resourceIconPath;
-	}
+    public void setResourceIconPath(String resourceIconPath) {
+        this.resourceIconPath = resourceIconPath;
+    }
 
-	public String getVendorName() {
-		return vendorName;
-	}
+    public String getVendorName() {
+        return vendorName;
+    }
 
-	public void setVendorName(String vendorName) {
-		this.vendorName = vendorName;
-	}
+    public void setVendorName(String vendorName) {
+        this.vendorName = vendorName;
+    }
 
-	public String getVendorRelease() {
-		return vendorRelease;
-	}
+    public String getVendorRelease() {
+        return vendorRelease;
+    }
 
-	public void setVendorRelease(String vendorRelease) {
-		this.vendorRelease = vendorRelease;
-	}
+    public void setVendorRelease(String vendorRelease) {
+        this.vendorRelease = vendorRelease;
+    }
 
-	public String getResourceVendorModelNumber() {
-		return resourceVendorModelNumber;
-	}
+    public String getResourceVendorModelNumber() {
+        return resourceVendorModelNumber;
+    }
 
-	public void setResourceVendorModelNumber(String resourceVendorModelNumber) {
-		this.resourceVendorModelNumber = resourceVendorModelNumber;
-	}
+    public void setResourceVendorModelNumber(String resourceVendorModelNumber) {
+        this.resourceVendorModelNumber = resourceVendorModelNumber;
+    }
 
-	public void setIcon(String icon) {
-		this.icon = icon;
-	}
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
 
-	public String getResourceType() {
-		return resourceType;
-	}
+    public String getResourceType() {
+        return resourceType;
+    }
 
-	public void setResourceType(String resourceType) {
-		this.resourceType = resourceType;
-	}
+    public void setResourceType(String resourceType) {
+        this.resourceType = resourceType;
+    }
 
-	public List<CategoryDefinition> getCategories() {
-		return categories;
-	}
+    public List<CategoryDefinition> getCategories() {
+        return categories;
+    }
 
-	public void setCategories(List<CategoryDefinition> categories) {
-		this.categories = categories;
-	}
+    public void setCategories(List<CategoryDefinition> categories) {
+        this.categories = categories;
+    }
 
-	public void addSubCategory(String category, String subCategory) {
-		if (category != null || subCategory != null) {
-			if (categories == null) {
-				categories = new ArrayList<>();
-			}
-			CategoryDefinition selectedCategory = null;
-			for (CategoryDefinition categoryDef : categories) {
-				if (categoryDef.getName().equals(category)) {
-					selectedCategory = categoryDef;
-				}
-			}
-			if (selectedCategory == null) {
-				selectedCategory = new CategoryDefinition();
-				selectedCategory.setName(category);
-				categories.add(selectedCategory);
-			}
-			List<SubCategoryDefinition> subcategories = selectedCategory.getSubcategories();
-			if (subcategories == null) {
-				subcategories = new ArrayList<>();
-				selectedCategory.setSubcategories(subcategories);
-			}
-			SubCategoryDefinition selectedSubcategory = null;
-			for (SubCategoryDefinition subcategory : subcategories) {
-				if (subcategory.getName().equals(subCategory)) {
-					selectedSubcategory = subcategory;
-				}
-			}
-			if (selectedSubcategory == null) {
-				selectedSubcategory = new SubCategoryDefinition();
-				selectedSubcategory.setName(subCategory);
-				subcategories.add(selectedSubcategory);
-			}
-		}
-	}
+    public void addSubCategory(String category, String subCategory) {
+        if (category != null || subCategory != null) {
+            if (categories == null) {
+                categories = new ArrayList<>();
+            }
+            CategoryDefinition selectedCategory = null;
+            for (CategoryDefinition categoryDef : categories) {
+                if (categoryDef.getName().equals(category)) {
+                    selectedCategory = categoryDef;
+                }
+            }
+            if (selectedCategory == null) {
+                selectedCategory = new CategoryDefinition();
+                selectedCategory.setName(category);
+                categories.add(selectedCategory);
+            }
+            List<SubCategoryDefinition> subcategories = selectedCategory.getSubcategories();
+            if (subcategories == null) {
+                subcategories = new ArrayList<>();
+                selectedCategory.setSubcategories(subcategories);
+            }
+            SubCategoryDefinition selectedSubcategory = null;
+            for (SubCategoryDefinition subcategory : subcategories) {
+                if (subcategory.getName().equals(subCategory)) {
+                    selectedSubcategory = subcategory;
+                }
+            }
+            if (selectedSubcategory == null) {
+                selectedSubcategory = new SubCategoryDefinition();
+                selectedSubcategory.setName(subCategory);
+                subcategories.add(selectedSubcategory);
+            }
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java
index b10214e..86d3d81 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java
@@ -26,183 +26,183 @@
 import org.openecomp.sdc.be.resources.data.UserData;
 
 public class User {
-	public static final String FORCE_DELETE_HEADER_FLAG = "FORCE_DELETE";
+    public static final String FORCE_DELETE_HEADER_FLAG = "FORCE_DELETE";
 
-	private String firstName;
+    private String firstName;
 
-	private String lastName;
+    private String lastName;
 
-	private String userId;
+    private String userId;
 
-	private String email;
+    private String email;
 
-	private String role;
+    private String role;
 
-	private Long lastLoginTime;
+    private Long lastLoginTime;
 
-	private UserStatusEnum status = UserStatusEnum.ACTIVE;
+    private UserStatusEnum status = UserStatusEnum.ACTIVE;
 
-	public User() {
-	}
+    public User() {
+    }
 
-	public User(UserData userData) {
-		this(userData.getFirstName(), userData.getLastName(), userData.getUserId(), userData.getEmail(),
-				userData.getRole(), userData.getLastLoginTime());
-	}
+    public User(UserData userDate) {
+        this(userDate.getFirstName(), userDate.getLastName(), userDate.getUserId(), userDate.getEmail(),
+                userDate.getRole(), userDate.getLastLoginTime());
+    }
 
-	public User(String firstName, String lastName, String userId, String emailAddress, String role,
-			Long lastLoginTime) {
-		this.firstName = firstName;
-		this.lastName = lastName;
-		this.userId = userId;
-		this.email = emailAddress;
-		this.role = role;
-		this.lastLoginTime = lastLoginTime;
+    public User(String firstName, String lastName, String userId, String emailAddress, String role,
+            Long lastLoginTime) {
+        this.firstName = firstName;
+        this.lastName = lastName;
+        this.userId = userId;
+        this.email = emailAddress;
+        this.role = role;
+        this.lastLoginTime = lastLoginTime;
 
-	}
+    }
 
-	public void copyData(User other) {
+    public void copyData(User other) {
 		if(other == null) {
 			return;
 		}
-		this.firstName = other.getFirstName();
-		this.lastName = other.getLastName();
-		this.userId = other.getUserId();
-		this.email = other.getEmail();
-		this.role = other.getRole();
-		this.lastLoginTime = other.getLastLoginTime();
+        this.firstName = other.getFirstName();
+        this.lastName = other.getLastName();
+        this.userId = other.getUserId();
+        this.email = other.getEmail();
+        this.role = other.getRole();
+        this.lastLoginTime = other.getLastLoginTime();
 
-	}
+    }
 
-	public User(User aUser) {
-		this(aUser.getFirstName(), aUser.getLastName(), aUser.getUserId(), aUser.getEmail(), aUser.getRole(),
-				aUser.getLastLoginTime());
-	}
+    public User(User aUser) {
+        this(aUser.getFirstName(), aUser.getLastName(), aUser.getUserId(), aUser.getEmail(), aUser.getRole(),
+                aUser.getLastLoginTime());
+    }
 
-	public String getFirstName() {
-		return firstName;
-	}
+    public String getFirstName() {
+        return firstName;
+    }
 
-	public void setFirstName(String firstName) {
-		this.firstName = firstName;
-	}
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
 
-	public String getLastName() {
-		return lastName;
-	}
+    public String getLastName() {
+        return lastName;
+    }
 
-	public void setLastName(String lastName) {
-		this.lastName = lastName;
-	}
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
 
-	public String getUserId() {
-		return userId;
-	}
+    public String getUserId() {
+        return userId;
+    }
 
-	public void setUserId(String userId) {
-		this.userId = userId;
-	}
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
 
-	public String getEmail() {
-		return email;
-	}
+    public String getEmail() {
+        return email;
+    }
 
-	public void setEmail(String email) {
-		this.email = email;
-	}
+    public void setEmail(String email) {
+        this.email = email;
+    }
 
-	public String getRole() {
-		return role;
-	}
+    public String getRole() {
+        return role;
+    }
 
-	public void setRole(String role) {
-		this.role = role;
-	}
+    public void setRole(String role) {
+        this.role = role;
+    }
 
-	public String getFullName() {
-		return this.getFirstName() + " " + this.getLastName();
-	}
+    public String getFullName() {
+        return this.getFirstName() + " " + this.getLastName();
+    }
 
-	public void setLastLoginTime() {
-		DateTime now = new DateTime(DateTimeZone.UTC);
-		this.lastLoginTime = now.getMillis();
-	}
+    public void setLastLoginTime() {
+        DateTime now = new DateTime(DateTimeZone.UTC);
+        this.lastLoginTime = now.getMillis();
+    }
 
-	public void setLastLoginTime(Long time) {
-		this.lastLoginTime = time;
-	}
+    public void setLastLoginTime(Long time) {
+        this.lastLoginTime = time;
+    }
 
-	public Long getLastLoginTime() {
-		return this.lastLoginTime;
-	}
+    public Long getLastLoginTime() {
+        return this.lastLoginTime;
+    }
 
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((userId == null) ? 0 : userId.hashCode());
-		result = prime * result + ((email == null) ? 0 : email.hashCode());
-		result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
-		result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
-		result = prime * result + ((role == null) ? 0 : role.hashCode());
-		result = prime * result + ((lastLoginTime == null) ? 0 : lastLoginTime.hashCode());
-		return result;
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((userId == null) ? 0 : userId.hashCode());
+        result = prime * result + ((email == null) ? 0 : email.hashCode());
+        result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
+        result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
+        result = prime * result + ((role == null) ? 0 : role.hashCode());
+        result = prime * result + ((lastLoginTime == null) ? 0 : lastLoginTime.hashCode());
+        return result;
+    }
 
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		User other = (User) obj;
-		if (userId == null) {
-			if (other.userId != null)
-				return false;
-		} else if (!userId.equals(other.userId))
-			return false;
-		if (email == null) {
-			if (other.email != null)
-				return false;
-		} else if (!email.equals(other.email))
-			return false;
-		if (firstName == null) {
-			if (other.firstName != null)
-				return false;
-		} else if (!firstName.equals(other.firstName))
-			return false;
-		if (lastName == null) {
-			if (other.lastName != null)
-				return false;
-		} else if (!lastName.equals(other.lastName))
-			return false;
-		if (role == null) {
-			if (other.role != null)
-				return false;
-		} else if (!role.equals(other.role))
-			return false;
-		if (lastLoginTime == null) {
-			if (other.lastLoginTime != null)
-				return false;
-		} else if (!lastLoginTime.equals(other.lastLoginTime))
-			return false;
-		return true;
-	}
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        User other = (User) obj;
+        if (userId == null) {
+            if (other.userId != null)
+                return false;
+        } else if (!userId.equals(other.userId))
+            return false;
+        if (email == null) {
+            if (other.email != null)
+                return false;
+        } else if (!email.equals(other.email))
+            return false;
+        if (firstName == null) {
+            if (other.firstName != null)
+                return false;
+        } else if (!firstName.equals(other.firstName))
+            return false;
+        if (lastName == null) {
+            if (other.lastName != null)
+                return false;
+        } else if (!lastName.equals(other.lastName))
+            return false;
+        if (role == null) {
+            if (other.role != null)
+                return false;
+        } else if (!role.equals(other.role))
+            return false;
+        if (lastLoginTime == null) {
+            if (other.lastLoginTime != null)
+                return false;
+        } else if (!lastLoginTime.equals(other.lastLoginTime))
+            return false;
+        return true;
+    }
 
-	public UserStatusEnum getStatus() {
-		return status;
-	}
+    public UserStatusEnum getStatus() {
+        return status;
+    }
 
-	public void setStatus(UserStatusEnum status) {
-		this.status = status;
-	}
+    public void setStatus(UserStatusEnum status) {
+        this.status = status;
+    }
 
-	@Override
-	public String toString() {
-		return "User [firstName=" + firstName + ", lastName=" + lastName + ", userId=" + userId + ", email=" + email
-				+ ", role=" + role + ", last login time=" + lastLoginTime + "]";
-	}
+    @Override
+    public String toString() {
+        return "User [firstName=" + firstName + ", lastName=" + lastName + ", userId=" + userId + ", email=" + email
+                + ", role=" + role + ", last login time=" + lastLoginTime + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java
index bb8a1b0..e9b7f7a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java
@@ -20,16 +20,15 @@
 
 package org.openecomp.sdc.be.model.cache;
 
-import java.util.Map;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 
-import fj.data.Either;
+import java.util.Map;
 
 public interface ApplicationCache<T> {
 
-	public abstract Either<Map<String, T>, TitanOperationStatus> getAll();
+    public abstract Either<Map<String, T>, TitanOperationStatus> getAll();
 
-	public abstract Either<T, TitanOperationStatus> get(String uniqueId);
+    public abstract Either<T, TitanOperationStatus> get(String uniqueId);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java
index 4c8d239..9499211 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java
@@ -20,6 +20,25 @@
 
 package org.openecomp.sdc.be.model.cache;
 
+import fj.data.Either;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
+import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheConfig;
+import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheInfo;
+import org.openecomp.sdc.be.config.ConfigurationManager;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
+import org.openecomp.sdc.be.resources.data.DataTypeData;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.annotation.Resource;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -33,302 +52,277 @@
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.stream.Collectors;
 
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.annotation.Resource;
-
-import org.apache.commons.lang3.concurrent.BasicThreadFactory;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.openecomp.sdc.be.config.BeEcompErrorManager;
-import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
-import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheConfig;
-import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheInfo;
-import org.openecomp.sdc.be.config.ConfigurationManager;
-import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
-import org.openecomp.sdc.be.resources.data.DataTypeData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import fj.data.Either;
-
 @Component("application-datatype-cache")
 public class ApplicationDataTypeCache implements ApplicationCache<DataTypeDefinition>, Runnable {
 
+    private static final String APPLICATION_DATA_TYPES_CACHE = "ApplicationDataTypesCache";
 	private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
-	private final Lock r = rwl.readLock();
-	private final Lock w = rwl.writeLock();
+    private final Lock r = rwl.readLock();
+    private final Lock w = rwl.writeLock();
 
-	private Map<String, DataTypeDefinition> data = new HashMap<>();
+    private Map<String, DataTypeDefinition> data = new HashMap<>();
 
-	private ScheduledExecutorService scheduledPollingService = Executors.newScheduledThreadPool(1,
-			new BasicThreadFactory.Builder().namingPattern("ApplicationDataTypeCacheThread-%d").build());
-	ScheduledFuture<?> scheduledFuture = null;
+    private ScheduledExecutorService scheduledPollingService = Executors.newScheduledThreadPool(1,
+            new BasicThreadFactory.Builder().namingPattern("ApplicationDataTypeCacheThread-%d").build());
+    ScheduledFuture<?> scheduledFuture = null;
 
-	private static Logger log = LoggerFactory.getLogger(ApplicationDataTypeCache.class.getName());
+    private static final Logger log = Logger.getLogger(ApplicationDataTypeCache.class.getName());
 
-	private int firstRunDelayInSec = 30;
-	private int pollingIntervalInSec = 60;
+    private int firstRunDelayInSec = 30;
+    private int pollingIntervalInSec = 60;
 
-	@Resource
-	private PropertyOperation propertyOperation;
+    @Resource
+    private PropertyOperation propertyOperation;
 
-	@PostConstruct
-	public void init() {
+    @PostConstruct
+    public void init() {
 
-		ApplicationL1CacheConfig applicationL1CacheConfig = ConfigurationManager.getConfigurationManager()
-				.getConfiguration().getApplicationL1Cache();
-		if (applicationL1CacheConfig != null) {
-			if (applicationL1CacheConfig.getDatatypes() != null) {
-				ApplicationL1CacheInfo datatypesInfo = applicationL1CacheConfig.getDatatypes();
-				if (datatypesInfo.getEnabled()) {
-					Integer intervalInSec = datatypesInfo.getPollIntervalInSec();
-					if (intervalInSec != null) {
-						pollingIntervalInSec = intervalInSec;
-					}
-					Integer firstRunDelay = datatypesInfo.getFirstRunDelay();
-					if (firstRunDelay != null) {
-						firstRunDelayInSec = firstRunDelay;
-					}
-					log.trace("ApplicationDataTypesCache polling interval is {} seconds.", pollingIntervalInSec);
-					if (scheduledPollingService != null) {
-						log.debug("Start ApplicationDataTypeCache polling task. polling interval {} seconds",
-								pollingIntervalInSec);
-						scheduledFuture = scheduledPollingService.scheduleAtFixedRate(this, firstRunDelayInSec,
-								pollingIntervalInSec, TimeUnit.SECONDS);
-					}
+        ApplicationL1CacheConfig applicationL1CacheConfig = ConfigurationManager.getConfigurationManager()
+                .getConfiguration().getApplicationL1Cache();
+        if (applicationL1CacheConfig != null) {
+            if (applicationL1CacheConfig.getDatatypes() != null) {
+                ApplicationL1CacheInfo datatypesInfo = applicationL1CacheConfig.getDatatypes();
+                if (datatypesInfo.getEnabled()) {
+                    Integer intervalInSec = datatypesInfo.getPollIntervalInSec();
+                    if (intervalInSec != null) {
+                        pollingIntervalInSec = intervalInSec;
+                    }
+                    Integer firstRunDelay = datatypesInfo.getFirstRunDelay();
+                    if (firstRunDelay != null) {
+                        firstRunDelayInSec = firstRunDelay;
+                    }
+                    log.trace("ApplicationDataTypesCache polling interval is {} seconds.", pollingIntervalInSec);
+                    if (scheduledPollingService != null) {
+                        log.debug("Start ApplicationDataTypeCache polling task. polling interval {} seconds",
+                                pollingIntervalInSec);
+                        scheduledFuture = scheduledPollingService.scheduleAtFixedRate(this, firstRunDelayInSec,
+                                pollingIntervalInSec, TimeUnit.SECONDS);
+                    }
 
-				}
-			} else {
-				BeEcompErrorManager.getInstance().logInternalFlowError("ApplicationDataTypesCache", "Cache is disabled",
-						ErrorSeverity.INFO);
-			}
-		} else {
-			BeEcompErrorManager.getInstance().logInternalFlowError("ApplicationDataTypesCache", "Cache is disabled",
-					ErrorSeverity.INFO);
-		}
+                }
+            } else {
+                BeEcompErrorManager.getInstance().logInternalFlowError(APPLICATION_DATA_TYPES_CACHE, "Cache is disabled",
+                        ErrorSeverity.INFO);
+            }
+        } else {
+            BeEcompErrorManager.getInstance().logInternalFlowError(APPLICATION_DATA_TYPES_CACHE, "Cache is disabled",
+                    ErrorSeverity.INFO);
+        }
 
-	}
+    }
 
-	@PreDestroy
-	void destroy() {
+    @PreDestroy
+    void destroy() {
 
-		if (scheduledFuture != null) {
-			boolean result = scheduledFuture.cancel(true);
-			log.debug("Stop polling task. result = {}", result);
+        if (scheduledFuture != null) {
+            boolean result = scheduledFuture.cancel(true);
+            log.debug("Stop polling task. result = {}", result);
 
-			scheduledFuture = null;
-		}
-		shutdownExecutor();
-	}
+            scheduledFuture = null;
+        }
+        shutdownExecutor();
+    }
 
-	private void shutdownExecutor() {
-		if (scheduledPollingService == null)
-			return;
+    private void shutdownExecutor() {
+        if (scheduledPollingService == null)
+            return;
 
-		scheduledPollingService.shutdown(); // Disable new tasks from being
-											// submitted
-		try {
-			// Wait a while for existing tasks to terminate
-			if (!scheduledPollingService.awaitTermination(60, TimeUnit.SECONDS)) {
-				scheduledPollingService.shutdownNow(); // Cancel currently
-														// executing tasks
-				// Wait a while for tasks to respond to being cancelled
-				if (!scheduledPollingService.awaitTermination(60, TimeUnit.SECONDS))
-					log.debug("Pool did not terminate");
-			}
-		} catch (InterruptedException ie) {
-			// (Re-)Cancel if current thread also interrupted
-			scheduledPollingService.shutdownNow();
-			// Preserve interrupt status
-			Thread.currentThread().interrupt();
-		}
-	}
+        scheduledPollingService.shutdown(); // Disable new tasks from being
+                                            // submitted
+        try {
+            // Wait a while for existing tasks to terminate
+            if (!scheduledPollingService.awaitTermination(60, TimeUnit.SECONDS)) {
+                scheduledPollingService.shutdownNow(); // Cancel currently
+                                                        // executing tasks
+                // Wait a while for tasks to respond to being cancelled
+                if (!scheduledPollingService.awaitTermination(60, TimeUnit.SECONDS))
+                    log.debug("Pool did not terminate");
+            }
+        } catch (InterruptedException ie) {
+            // (Re-)Cancel if current thread also interrupted
+            scheduledPollingService.shutdownNow();
+            // Preserve interrupt status
+            Thread.currentThread().interrupt();
+        }
+    }
 
-	private Either<Map<String, DataTypeDefinition>, TitanOperationStatus> getAllDataTypesFromGraph() {
+    private Either<Map<String, DataTypeDefinition>, TitanOperationStatus> getAllDataTypesFromGraph() {
 
-		Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = propertyOperation
-				.getAllDataTypes();
+        return propertyOperation
+                .getAllDataTypes();
 
-		return allDataTypes;
+    }
 
-	}
+    @Override
+    public Either<Map<String, DataTypeDefinition>, TitanOperationStatus> getAll() {
 
-	@Override
-	public Either<Map<String, DataTypeDefinition>, TitanOperationStatus> getAll() {
+        try {
 
-		try {
+            r.lock();
+            if (data == null || data.isEmpty()) {
+                return getAllDataTypesFromGraph();
+            }
 
-			r.lock();
-			if (data == null || data.isEmpty()) {
-				return getAllDataTypesFromGraph();
-			}
+            return Either.left(data);
 
-			return Either.left(data);
+        } finally {
+            r.unlock();
+        }
+    }
 
-		} finally {
-			r.unlock();
-		}
-	}
+    @Override
+    public Either<DataTypeDefinition, TitanOperationStatus> get(String uniqueId) {
 
-	@Override
-	public Either<DataTypeDefinition, TitanOperationStatus> get(String uniqueId) {
+        try {
+            r.lock();
 
-		try {
-			r.lock();
+            if (data == null || data.isEmpty()) {
+                return propertyOperation
+                        .getDataTypeByUid(uniqueId);
+            } else {
+                DataTypeDefinition dataTypeDefinition = data.values().stream()
+                        .filter(p -> p.getUniqueId().equals(uniqueId)).findFirst().orElse(null);
+                if (dataTypeDefinition == null) {
+                    return propertyOperation
+                            .getDataTypeByUid(uniqueId);
+                } else {
+                    return Either.left(dataTypeDefinition);
+                }
+            }
+        } finally {
+            r.unlock();
+        }
+    }
 
-			if (data == null || data.isEmpty()) {
-				Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = propertyOperation
-						.getDataTypeByUid(uniqueId);
-				return dataTypeByUid;
-			} else {
-				DataTypeDefinition dataTypeDefinition = data.values().stream()
-						.filter(p -> p.getUniqueId().equals(uniqueId)).findFirst().orElse(null);
-				if (dataTypeDefinition == null) {
-					Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = propertyOperation
-							.getDataTypeByUid(uniqueId);
-					return dataTypeByUid;
-				} else {
-					return Either.left(dataTypeDefinition);
-				}
-			}
-		} finally {
-			r.unlock();
-		}
-	}
+    @Override
+    public void run() {
+        log.trace("run() method. polling db to fetch data types");
 
-	@Override
-	public void run() {
-		log.trace("run() method. polling db to fetch data types");
+        try {
 
-		try {
+            Long start = System.currentTimeMillis();
+            log.trace("Start fetching all data types from db");
+            Either<List<DataTypeData>, TitanOperationStatus> allDataTypeNodes = propertyOperation.getAllDataTypeNodes();
+            Long end = System.currentTimeMillis();
+            log.trace("Finish fetching all data types from db. Took {} Milliseconds", (end - start));
+            if (allDataTypeNodes.isRight()) {
+                TitanOperationStatus status = allDataTypeNodes.right().value();
+                if (status != TitanOperationStatus.OK) {
+                    log.debug("ApplicationDataTypesCache - Failed to fetch all data types nodes");
+                    BeEcompErrorManager.getInstance().logInternalConnectionError("FetchDataTypes",
+                            "Failed to fetch data types from graph(cache)", ErrorSeverity.INFO);
+                }
+            } else {
 
-			Long start = System.currentTimeMillis();
-			log.trace("Start fetching all data types from db");
-			Either<List<DataTypeData>, TitanOperationStatus> allDataTypeNodes = propertyOperation.getAllDataTypeNodes();
-			Long end = System.currentTimeMillis();
-			log.trace("Finish fetching all data types from db. Took {} Milliseconds", (end - start));
-			if (allDataTypeNodes.isRight()) {
-				TitanOperationStatus status = allDataTypeNodes.right().value();
-				if (status != TitanOperationStatus.OK) {
-					log.debug("ApplicationDataTypesCache - Failed to fetch all data types nodes");
-					BeEcompErrorManager.getInstance().logInternalConnectionError("FetchDataTypes",
-							"Failed to fetch data types from graph(cache)", ErrorSeverity.INFO);
-				}
-			} else {
+                List<DataTypeData> list = allDataTypeNodes.left().value();
+                if (list != null) {
 
-				List<DataTypeData> list = allDataTypeNodes.left().value();
-				if (list != null) {
+                    Map<String, ImmutablePair<Long, Long>> dataTypeNameToModificationTime = list.stream()
+                            .collect(Collectors.toMap(p -> p.getDataTypeDataDefinition().getName(),
+                                    p -> new ImmutablePair<>(p.getDataTypeDataDefinition().getCreationTime(),
+                                            p.getDataTypeDataDefinition().getModificationTime())));
 
-					Map<String, ImmutablePair<Long, Long>> dataTypeNameToModificationTime = list.stream()
-							.collect(Collectors.toMap(p -> p.getDataTypeDataDefinition().getName(),
-									p -> new ImmutablePair<Long, Long>(p.getDataTypeDataDefinition().getCreationTime(),
-											p.getDataTypeDataDefinition().getModificationTime())));
+                    Map<String, ImmutablePair<Long, Long>> currentDataTypeToModificationTime = new HashMap<>();
+                    try {
+                        r.lock();
+                        if (data != null) {
+                            currentDataTypeToModificationTime = data.values().stream().collect(Collectors.toMap(
+                                    DataTypeDataDefinition::getName,
+                                    p -> new ImmutablePair<>(p.getCreationTime(), p.getModificationTime())));
 
-					Map<String, ImmutablePair<Long, Long>> currentDataTypeToModificationTime = new HashMap<>();
-					try {
-						r.lock();
-						if (data != null) {
-							currentDataTypeToModificationTime = data.values().stream().collect(Collectors.toMap(
-									p -> p.getName(),
-									p -> new ImmutablePair<Long, Long>(p.getCreationTime(), p.getModificationTime())));
+                        }
+                    } finally {
+                        r.unlock();
+                    }
 
-						}
-					} finally {
-						r.unlock();
-					}
+                    boolean isChanged = compareDataTypes(dataTypeNameToModificationTime,
+                            currentDataTypeToModificationTime);
+                    if (isChanged) {
+                        replaceAllData();
+                    }
 
-					boolean isChanged = compareDataTypes(dataTypeNameToModificationTime,
-							currentDataTypeToModificationTime);
-					if (isChanged) {
-						replaceAllData();
-					}
+                }
+            }
 
-				}
-			}
+        } catch (Exception e) {
+            log.debug("unexpected error occured", e);
 
-		} catch (Exception e) {
-			log.debug("unexpected error occured", e);
+            BeEcompErrorManager.getInstance().logInternalUnexpectedError(APPLICATION_DATA_TYPES_CACHE,
+                    "Failed to run refresh data types job", ErrorSeverity.INFO);
+        } finally {
+            try {
+                propertyOperation.getTitanGenericDao().commit();
+            } catch (Exception e) {
+                log.trace("Failed to commit ApplicationDataTypeCache", e);
+            }
+        }
 
-			BeEcompErrorManager.getInstance().logInternalUnexpectedError("ApplicationDataTypesCache",
-					"Failed to run refresh data types job", ErrorSeverity.INFO);
-		} finally {
-			try {
-				propertyOperation.getTitanGenericDao().commit();
-			} catch (Exception e) {
-				log.trace("Failed to commit ApplicationDataTypeCache", e);
-			}
-		}
+    }
 
-	}
+    private boolean compareDataTypes(Map<String, ImmutablePair<Long, Long>> dataTypeNameToModificationTime,
+            Map<String, ImmutablePair<Long, Long>> currentDataTypeToModificationTime) {
+        if (dataTypeNameToModificationTime.size() != currentDataTypeToModificationTime.size()) {
+            return true;
+        } else {
 
-	private boolean compareDataTypes(Map<String, ImmutablePair<Long, Long>> dataTypeNameToModificationTime,
-			Map<String, ImmutablePair<Long, Long>> currentDataTypeToModificationTime) {
-		if (dataTypeNameToModificationTime.size() != currentDataTypeToModificationTime.size()) {
-			return true;
-		} else {
+            Set<String> currentkeySet = currentDataTypeToModificationTime.keySet();
+            Set<String> keySet = dataTypeNameToModificationTime.keySet();
 
-			Set<String> currentkeySet = currentDataTypeToModificationTime.keySet();
-			Set<String> keySet = dataTypeNameToModificationTime.keySet();
+            if (currentkeySet.containsAll(keySet)) {
 
-			if (currentkeySet.containsAll(keySet)) {
+                for (Entry<String, ImmutablePair<Long, Long>> entry : dataTypeNameToModificationTime.entrySet()) {
+                    String dataTypeName = entry.getKey();
+                    ImmutablePair<Long, Long> creationAndModificationTimes = entry.getValue();
+                    long creationTime = creationAndModificationTimes.getLeft() == null ? 0
+                            : creationAndModificationTimes.getLeft().longValue();
+                    long modificationTime = creationAndModificationTimes.getRight() == null ? 0
+                            : creationAndModificationTimes.getRight().longValue();
 
-				for (Entry<String, ImmutablePair<Long, Long>> entry : dataTypeNameToModificationTime.entrySet()) {
-					String dataTypeName = entry.getKey();
-					ImmutablePair<Long, Long> creationAndModificationTimes = entry.getValue();
-					long creationTime = creationAndModificationTimes.getLeft() == null ? 0
-							: creationAndModificationTimes.getLeft().longValue();
-					long modificationTime = creationAndModificationTimes.getRight() == null ? 0
-							: creationAndModificationTimes.getRight().longValue();
+                    ImmutablePair<Long, Long> currentEntry = currentDataTypeToModificationTime.get(dataTypeName);
+                    long currentCreationTime = currentEntry.getLeft() == null ? 0 : currentEntry.getLeft().longValue();
+                    long currentModificationTime = currentEntry.getRight() == null ? 0
+                            : currentEntry.getRight().longValue();
 
-					ImmutablePair<Long, Long> currentEntry = currentDataTypeToModificationTime.get(dataTypeName);
-					long currentCreationTime = currentEntry.getLeft() == null ? 0 : currentEntry.getLeft().longValue();
-					long currentModificationTime = currentEntry.getRight() == null ? 0
-							: currentEntry.getRight().longValue();
+                    if (creationTime > currentCreationTime || modificationTime > currentModificationTime) {
+                        log.debug("Datatype {} was updated. Creation Time  {} vs {}. Modification Time {} vs {}",
+                                dataTypeName, currentCreationTime, creationTime, currentModificationTime,
+                                modificationTime);
+                        return true;
+                    }
+                }
+            } else {
+                return true;
+            }
 
-					if (creationTime > currentCreationTime || modificationTime > currentModificationTime) {
-						log.debug("Datatype {} was updated. Creation Time  {} vs {}. Modification Time {} vs {}",
-								dataTypeName, currentCreationTime, creationTime, currentModificationTime,
-								modificationTime);
-						return true;
-					}
-				}
-			} else {
-				return true;
-			}
+        }
 
-		}
+        return false;
+    }
 
-		return false;
-	}
+    private void replaceAllData() {
 
-	private void replaceAllData() {
+        Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = propertyOperation
+                .getAllDataTypes();
 
-		Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = propertyOperation
-				.getAllDataTypes();
+        if (allDataTypes.isRight()) {
+            TitanOperationStatus status = allDataTypes.right().value();
+            log.debug("Failed to fetch all data types from db. Status is {}", status);
+        } else {
 
-		if (allDataTypes.isRight()) {
-			TitanOperationStatus status = allDataTypes.right().value();
-			log.debug("Failed to fetch all data types from db. Status is {}", status);
-		} else {
+            try {
+                w.lock();
 
-			try {
-				w.lock();
+                data = allDataTypes.left().value();
 
-				Map<String, DataTypeDefinition> newDataTypes = allDataTypes.left().value();
-				data = newDataTypes;
+                BeEcompErrorManager.getInstance().logInternalFlowError("ReplaceDataTypesCache",
+                        "Succeed to replace the data types cache", ErrorSeverity.INFO);
 
-				BeEcompErrorManager.getInstance().logInternalFlowError("ReplaceDataTypesCache",
-						"Succeed to replace the data types cache", ErrorSeverity.INFO);
+            } finally {
+                w.unlock();
+            }
 
-			} finally {
-				w.unlock();
-			}
+        }
 
-		}
-
-	}
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java
index 4fa41e5..b17a664 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java
@@ -36,27 +36,21 @@
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.LifecycleStateEnum;
-import org.openecomp.sdc.be.model.Product;
-import org.openecomp.sdc.be.model.Resource;
-import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
-import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.resources.data.ComponentCacheData;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.SerializationUtils;
 import org.openecomp.sdc.common.util.ZipUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import javax.annotation.PostConstruct;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
+import java.util.*;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -68,817 +62,853 @@
 @org.springframework.stereotype.Component("component-cache")
 public class ComponentCache {
 
-	private static Logger logger = LoggerFactory.getLogger(ComponentCache.class.getName());
+    private static final String COMPONENT_CACHE_IS_DISABLED = "Component Cache is disabled";
 
-	@Autowired
-	ComponentCassandraDao componentCassandraDao;
+	private static final Logger log = Logger.getLogger(ComponentCache.class);
 
-	@Autowired
-	ToscaOperationFacade toscaOperationFacade;
+    @Autowired
+    ComponentCassandraDao componentCassandraDao;
 
-	private Map<ComponentTypeEnum, Map<String, Component>> catalogInMemoryCache = new HashMap<>();
-	private final ReentrantReadWriteLock rwCatalogLock = new ReentrantReadWriteLock();
-	private final Lock rCatalogLock = rwCatalogLock.readLock();
-	private final Lock wCatalogLock = rwCatalogLock.writeLock();
+    @Autowired
+    ToscaOperationFacade toscaOperationFacade;
 
-	boolean enabled = true;
-	int catalogInMemorySizePerResource = 300;
-	int catalogInMemorySizePerService = 200;
-	int catalogInMemorySizePerProduct = 100;
-	boolean catalogInMemoryEnabled = true;
-	Map<ComponentTypeEnum, Integer> limitMemoryCatalogSizePerType = new HashMap<>();
+    private Map<ComponentTypeEnum, Map<String, Component>> catalogInMemoryCache = new HashMap<>();
+    private final ReentrantReadWriteLock rwCatalogLock = new ReentrantReadWriteLock();
+    private final Lock rCatalogLock = rwCatalogLock.readLock();
+    private final Lock wCatalogLock = rwCatalogLock.writeLock();
 
-	@PostConstruct
-	public void init() {
+    boolean enabled = true;
+    int catalogInMemorySizePerResource = 300;
+    int catalogInMemorySizePerService = 200;
+    int catalogInMemorySizePerProduct = 100;
+    boolean catalogInMemoryEnabled = true;
+    Map<ComponentTypeEnum, Integer> limitMemoryCatalogSizePerType = new HashMap<>();
 
-		Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
-		if (configuration != null) {
-			ApplicationL2CacheConfig applicationL2Cache = configuration.getApplicationL2Cache();
-			if (applicationL2Cache != null) {
-				boolean isEnabled = applicationL2Cache.isEnabled();
-				this.enabled = isEnabled;
+    @PostConstruct
+    public void init() {
 
-				ApplicationL1CacheCatalogInfo catalog = applicationL2Cache.getCatalogL1Cache();
-				if (catalog != null) {
-					catalogInMemoryEnabled = catalog.getEnabled();
-					catalogInMemorySizePerResource = catalog.getResourcesSizeInCache();
-					catalogInMemorySizePerService = catalog.getServicesSizeInCache();
-					catalogInMemorySizePerProduct = catalog.getProductsSizeInCache();
-				}
-			}
-		}
+        Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
+        if (configuration != null) {
+            ApplicationL2CacheConfig applicationL2Cache = configuration.getApplicationL2Cache();
+            if (applicationL2Cache != null) {
+                this.enabled = applicationL2Cache.isEnabled();
 
-		ComponentTypeEnum[] typesForCache = { ComponentTypeEnum.RESOURCE, ComponentTypeEnum.SERVICE,
-				ComponentTypeEnum.PRODUCT };
-		for (ComponentTypeEnum typeEnum : typesForCache) {
-			Map<String, Component> map = new HashMap<>();
-			catalogInMemoryCache.put(typeEnum, map);
-		}
+                ApplicationL1CacheCatalogInfo catalog = applicationL2Cache.getCatalogL1Cache();
+                if (catalog != null) {
+                    catalogInMemoryEnabled = catalog.getEnabled();
+                    catalogInMemorySizePerResource = catalog.getResourcesSizeInCache();
+                    catalogInMemorySizePerService = catalog.getServicesSizeInCache();
+                    catalogInMemorySizePerProduct = catalog.getProductsSizeInCache();
+                }
+            }
+        }
 
-		limitMemoryCatalogSizePerType.put(ComponentTypeEnum.RESOURCE, catalogInMemorySizePerResource);
-		limitMemoryCatalogSizePerType.put(ComponentTypeEnum.SERVICE, catalogInMemorySizePerService);
-		limitMemoryCatalogSizePerType.put(ComponentTypeEnum.PRODUCT, catalogInMemorySizePerProduct);
-	}
+        ComponentTypeEnum[] typesForCache = { ComponentTypeEnum.RESOURCE, ComponentTypeEnum.SERVICE,
+                ComponentTypeEnum.PRODUCT };
+        for (ComponentTypeEnum typeEnum : typesForCache) {
+            Map<String, Component> map = new HashMap<>();
+            catalogInMemoryCache.put(typeEnum, map);
+        }
 
-	public boolean isEnabled() {
-		return enabled;
-	}
+        limitMemoryCatalogSizePerType.put(ComponentTypeEnum.RESOURCE, catalogInMemorySizePerResource);
+        limitMemoryCatalogSizePerType.put(ComponentTypeEnum.SERVICE, catalogInMemorySizePerService);
+        limitMemoryCatalogSizePerType.put(ComponentTypeEnum.PRODUCT, catalogInMemorySizePerProduct);
+    }
 
-	public void setEnabled(boolean enabled) {
-		this.enabled = enabled;
-	}
+    public boolean isEnabled() {
+        return enabled;
+    }
 
-	public Either<Component, ActionStatus> getComponent(String componentUid, Long lastModificationTime,
-			Function<Component, Component> filterFieldsFunc) {
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
 
-		Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> componentFromCache = getComponentFromCache(
-				componentUid, lastModificationTime, filterFieldsFunc);
+    public Either<Component, ActionStatus> getComponent(String componentUid, Long lastModificationTime,
+            Function<Component, Component> filterFieldsFunc) {
 
-		if (componentFromCache.isRight()) {
-			return Either.right(componentFromCache.right().value());
-		}
+        Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> componentFromCache = getComponentFromCache(
+                componentUid, lastModificationTime, filterFieldsFunc);
 
-		return Either.left(componentFromCache.left().value().left);
+        if (componentFromCache.isRight()) {
+            return Either.right(componentFromCache.right().value());
+        }
 
-	}
+        return Either.left(componentFromCache.left().value().left);
 
-	public Either<List<ComponentCacheData>, ActionStatus> getAllComponentIdTimeAndType() {
-		if (false == isEnabled()) {
-			return Either.right(ActionStatus.NOT_ALLOWED);
-		}
+    }
 
-		Either<List<ComponentCacheData>, ActionStatus> componentRes = componentCassandraDao
-				.getAllComponentIdTimeAndType();
+    public Either<List<ComponentCacheData>, ActionStatus> getAllComponentIdTimeAndType() {
+        if (!isEnabled()) {
+            return Either.right(ActionStatus.NOT_ALLOWED);
+        }
 
-		return componentRes;
+        return componentCassandraDao
+                .getAllComponentIdTimeAndType();
 
-	}
+    }
 
-	/**
-	 * @param foundComponents
-	 * @param componentTypeEnum
-	 */
-	private void updateCatalogInMemoryCacheWithCertified(List<Component> foundComponents,
-			ComponentTypeEnum componentTypeEnum) {
+    /**
+     * get components for catalog
+     *
+     * @param components
+     * @param componentTypeEnum
+     * @return
+     */
+    @Deprecated
+    public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsForCatalog(
+            Set<String> components, ComponentTypeEnum componentTypeEnum) {
 
-		try {
-			wCatalogLock.lock();
+        if (!isEnabled()) {
+            log.debug("In getComponentsForCatalog for type {}. Cache is disabled.",
+                    componentTypeEnum.name().toLowerCase());
+            return Either.right(ActionStatus.NOT_ALLOWED);
+        }
+        log.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase());
 
-			long start = System.currentTimeMillis();
-			Map<String, Component> map = catalogInMemoryCache.get(componentTypeEnum);
-			int mapSizeBefore = map.size();
-			map.clear();
-			Map<String, Component> collect = foundComponents.stream()
-					.filter(p -> p.getLifecycleState() == LifecycleStateEnum.CERTIFIED)
-					.limit(limitMemoryCatalogSizePerType.get(componentTypeEnum))
-					.collect(Collectors.toMap(p -> p.getUniqueId(), p -> p));
-			map.putAll(collect);
-			logger.debug(
-					"Size of in memory cache for catalog {}(certified only): Before {}, After {}. Replacement Time is {} ms.",
-					componentTypeEnum.name().toLowerCase(), mapSizeBefore, map.size(),
-					System.currentTimeMillis() - start);
-		} finally {
-			wCatalogLock.unlock();
-		}
+        Function<List<Component>, List<Component>> filterFieldsFunc = this::filterForCatalog;
 
-	}
+        Set<String> leftComponentsForSearch = new HashSet<>();
+        leftComponentsForSearch.addAll(components);
 
-	private List<Component> getDataFromInMemoryCache(Set<String> components, ComponentTypeEnum componentTypeEnum) {
-		List<Component> foundComponents = new ArrayList<>();
+        // get components from inmemory cache
+        List<Component> componentsFromMemory = null;
+        if (catalogInMemoryEnabled) {
+            componentsFromMemory = getDataFromInMemoryCache(components, componentTypeEnum);
+            log.debug("The number of components of type {} fetched from memory is {}",
+                    componentTypeEnum.name().toLowerCase(),
+                    componentsFromMemory == null ? 0 : componentsFromMemory.size());
+            if (componentsFromMemory != null) {
+                componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId()));
+            }
+        } else {
+            log.debug("Catalog InMemory cache is disabled");
+        }
 
-		try {
+        log.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(),
+                leftComponentsForSearch.size());
 
-			rCatalogLock.lock();
+        // get components from cassandra cache and filter each component
+        Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result = getComponents(
+                leftComponentsForSearch, filterFieldsFunc);
 
-			Map<String, Component> map = catalogInMemoryCache.get(componentTypeEnum);
-			for (String compUid : components) {
-				Component component = map.get(compUid);
-				if (component != null) {
-					foundComponents.add(component);
-				}
-			}
+        if (result.isLeft()) {
+            // add inmemory components to the valid components(not dirty)
+            List<Component> foundComponents = result.left().value().getLeft();
+            if (componentsFromMemory != null) {
+                foundComponents.addAll(componentsFromMemory);
+            }
+            if (catalogInMemoryEnabled) {
+                updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum);
+            }
+        }
 
-		} finally {
-			rCatalogLock.unlock();
-		}
+        return result;
+    }
 
-		return foundComponents;
-	}
+    /**
+     * @param foundComponents
+     * @param componentTypeEnum
+     */
+    private void updateCatalogInMemoryCacheWithCertified(List<Component> foundComponents,
+            ComponentTypeEnum componentTypeEnum) {
 
-	/**
-	 *
-	 * get full components from cassandra. On each component apply filter function
-	 * in order to remove unused members
-	 *
-	 * @param components
-	 * @param filterFieldsFunc
-	 * @return <found components, found dirty components, not found components list>
-	 *         or Error
-	 */
-	public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponents(
-			Set<String> components, Function<List<Component>, List<Component>> filterFieldsFunc) {
+        try {
+            wCatalogLock.lock();
 
-		if (false == isEnabled()) {
-			logger.debug("Component Cache is disabled");
-			return Either.right(ActionStatus.NOT_ALLOWED);
-		}
+            long start = System.currentTimeMillis();
+            Map<String, Component> map = catalogInMemoryCache.get(componentTypeEnum);
+            int mapSizeBefore = map.size();
+            map.clear();
+            Map<String, Component> collect = foundComponents.stream()
+                    .filter(p -> p.getLifecycleState() == LifecycleStateEnum.CERTIFIED)
+                    .limit(limitMemoryCatalogSizePerType.get(componentTypeEnum))
+                    .collect(Collectors.toMap(Component::getUniqueId, p -> p));
+            map.putAll(collect);
+            log.debug(
+                    "Size of in memory cache for catalog {}(certified only): Before {}, After {}. Replacement Time is {} ms.",
+                    componentTypeEnum.name().toLowerCase(), mapSizeBefore, map.size(),
+                    System.currentTimeMillis() - start);
+        } finally {
+            wCatalogLock.unlock();
+        }
 
-		Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> componentsFull = getComponentsFull(
-				components);
+    }
 
-		if (componentsFull.isRight()) {
-			return Either.right(componentsFull.right().value());
-		}
+    private List<Component> getDataFromInMemoryCache(Set<String> components, ComponentTypeEnum componentTypeEnum) {
+        List<Component> foundComponents = new ArrayList<>();
 
-		ImmutableTriple<List<Component>, List<Component>, Set<String>> immutableTriple = componentsFull.left().value();
-		List<Component> foundResources = immutableTriple.left;
-		List<Component> foundDirtyResources = immutableTriple.middle;
-		Set<String> notFoundResources = immutableTriple.right;
+        try {
 
-		List<Component> filterdFoundResources = filterFieldsFunc.apply(foundResources);
-		List<Component> filterdFoundDirtyResources = filterFieldsFunc.apply(foundDirtyResources);
+            rCatalogLock.lock();
 
-		ImmutableTriple<List<Component>, List<Component>, Set<String>> result = new ImmutableTriple<List<Component>, List<Component>, Set<String>>(
-				filterdFoundResources, filterdFoundDirtyResources, notFoundResources);
+            Map<String, Component> map = catalogInMemoryCache.get(componentTypeEnum);
+            for (String compUid : components) {
+                Component component = map.get(compUid);
+                if (component != null) {
+                    foundComponents.add(component);
+                }
+            }
 
-		return Either.left(result);
+        } finally {
+            rCatalogLock.unlock();
+        }
 
-	}
+        return foundComponents;
+    }
 
-	public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsForLeftPanel(
-			ComponentTypeEnum componentTypeEnum, String internalComponentType, Set<String> filteredResources) {
+    /**
+     *
+     * get full components from cassandra. On each component apply filter
+     * function in order to remove unused members
+     *
+     * @param components
+     * @param filterFieldsFunc
+     * @return <found components, found dirty components, not found components
+     *         list> or Error
+     */
+    public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponents(
+            Set<String> components, Function<List<Component>, List<Component>> filterFieldsFunc) {
 
-		logger.debug("In getComponentsForLeftPanel componentTypeEnum = {}, internalComponentType = {}",
-				componentTypeEnum, internalComponentType);
+        if (!isEnabled()) {
+            log.debug(COMPONENT_CACHE_IS_DISABLED);
+            return Either.right(ActionStatus.NOT_ALLOWED);
+        }
 
-		Function<List<Component>, List<Component>> filterFieldsFunc = x -> filterForLeftPanel(x);
+        Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> componentsFull = getComponentsFull(
+                components);
 
-		return getComponents(filteredResources, filterFieldsFunc);
+        if (componentsFull.isRight()) {
+            return Either.right(componentsFull.right().value());
+        }
 
-	}
+        ImmutableTriple<List<Component>, List<Component>, Set<String>> immutableTriple = componentsFull.left().value();
+        List<Component> foundResources = immutableTriple.left;
+        List<Component> foundDirtyResources = immutableTriple.middle;
+        Set<String> notFoundResources = immutableTriple.right;
 
-	private List<Component> filterForLeftPanel(List<Component> components) {
+        List<Component> filterdFoundResources = filterFieldsFunc.apply(foundResources);
+        List<Component> filterdFoundDirtyResources = filterFieldsFunc.apply(foundDirtyResources);
 
-		List<Component> result = new ArrayList<>();
-		if (components != null) {
-			components.forEach(p -> result.add(filterFieldsForLeftPanel(p)));
-		}
+        ImmutableTriple<List<Component>, List<Component>, Set<String>> result = new ImmutableTriple<>(
+                filterdFoundResources, filterdFoundDirtyResources, notFoundResources);
 
-		return result;
-	}
+        return Either.left(result);
 
-	private List<Component> filterForCatalog(List<Component> components) {
+    }
 
-		List<Component> result = new ArrayList<>();
-		if (components != null) {
-			components.forEach(p -> result.add(filterFieldsForCatalog(p)));
-		}
+    public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsForLeftPanel(
+            ComponentTypeEnum componentTypeEnum, String internalComponentType, Set<String> filteredResources) {
 
-		return result;
-	}
+        log.debug("In getComponentsForLeftPanel componentTypeEnum = {}, internalComponentType = {}",
+                componentTypeEnum, internalComponentType);
 
-	private Component filterFieldsForLeftPanel(Component component) {
+        Function<List<Component>, List<Component>> filterFieldsFunc = this::filterForLeftPanel;
 
-		Component result = null;
-		ComponentTypeEnum componentTypeEnum = component.getComponentType();
-		switch (componentTypeEnum) {
-		case RESOURCE:
-			result = new Resource();
-			copyFieldsForLeftPanel(component, result);
-			break;
-		case SERVICE:
-			result = new Service();
-			copyFieldsForLeftPanel(component, result);
-			break;
-		default:
-			break;
-		}
+        return getComponents(filteredResources, filterFieldsFunc);
 
-		return result;
-	}
+    }
 
-	private Component filterFieldsForCatalog(Component component) {
+    private List<Component> filterForLeftPanel(List<Component> components) {
 
-		Component result = null;
-		ComponentTypeEnum componentTypeEnum = component.getComponentType();
-		switch (componentTypeEnum) {
-		case RESOURCE:
-			result = new Resource();
-			copyFieldsForCatalog(component, result);
-			break;
-		case SERVICE:
-			result = new Service();
-			copyFieldsForCatalog(component, result);
-			break;
-		case PRODUCT:
-			result = new Product();
-			copyFieldsForCatalog(component, result);
-		default:
-			break;
-		}
+        List<Component> result = new ArrayList<>();
+        if (components != null) {
+            components.forEach(p -> result.add(filterFieldsForLeftPanel(p)));
+        }
 
-		return result;
-	}
+        return result;
+    }
 
-	/**
-	 * Copy relevant fields to the filtered component for left panel
-	 *
-	 * @param component
-	 * @param filteredComponent
-	 */
-	private void copyFieldsForLeftPanel(Component component, Component filteredComponent) {
+    private List<Component> filterForCatalog(List<Component> components) {
 
-		ComponentTypeEnum componentTypeEnum = component.getComponentType();
-		filteredComponent.setCategories(component.getCategories());
-		filteredComponent.setComponentType(component.getComponentType());
-		if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType())
-				&& ResourceTypeEnum.VL.equals(((ResourceMetadataDataDefinition) component
-						.getComponentMetadataDefinition().getMetadataDataDefinition()).getResourceType())) {
-			filteredComponent.setCapabilities(component.getCapabilities());
-			filteredComponent.setRequirements(component.getRequirements());
-		}
-		filteredComponent.setVersion(component.getVersion());
-		filteredComponent.setDescription(component.getDescription());
-		filteredComponent.setUniqueId(component.getUniqueId());
-		filteredComponent.setIcon(component.getIcon());
-		filteredComponent.setTags(component.getTags());
-		filteredComponent.setLifecycleState(component.getLifecycleState());
-		filteredComponent.setInvariantUUID(component.getInvariantUUID());
-		filteredComponent.setUUID(component.getUUID());
-		filteredComponent.setSystemName(component.getSystemName());
-		filteredComponent.setName(component.getName());
+        List<Component> result = new ArrayList<>();
+        if (components != null) {
+            components.forEach(p -> result.add(filterFieldsForCatalog(p)));
+        }
 
-		if (componentTypeEnum == ComponentTypeEnum.RESOURCE) {
-			Resource resource = (Resource) component;
-			Resource filteredResource = (Resource) filteredComponent;
-			filteredResource.setToscaResourceName(resource.getToscaResourceName());
-			filteredResource.setResourceType(resource.getResourceType());
-		}
-	}
+        return result;
+    }
 
-	private void copyFieldsForCatalog(Component component, Component filteredComponent) {
+    private Component filterFieldsForLeftPanel(Component component) {
 
-		ComponentTypeEnum componentTypeEnum = component.getComponentType();
-		filteredComponent.setCategories(component.getCategories());
-		filteredComponent.setComponentType(component.getComponentType());
-		filteredComponent.setVersion(component.getVersion());
-		filteredComponent.setDescription(component.getDescription());
-		filteredComponent.setUniqueId(component.getUniqueId());
-		filteredComponent.setIcon(component.getIcon());
-		filteredComponent.setTags(component.getTags());
-		filteredComponent.setLifecycleState(component.getLifecycleState());
-		filteredComponent.setSystemName(component.getSystemName());
-		filteredComponent.setName(component.getName());
-		filteredComponent.setLastUpdateDate(component.getLastUpdateDate());
+        Component result = null;
+        ComponentTypeEnum componentTypeEnum = component.getComponentType();
+        switch (componentTypeEnum) {
+        case RESOURCE:
+            result = new Resource();
+            copyFieldsForLeftPanel(component, result);
+            break;
+        case SERVICE:
+            result = new Service();
+            copyFieldsForLeftPanel(component, result);
+            break;
+        default:
+            break;
+        }
 
-		if (componentTypeEnum == ComponentTypeEnum.RESOURCE) {
-			Resource resource = (Resource) component;
-			Resource filteredResource = (Resource) filteredComponent;
-			filteredResource.setToscaResourceName(resource.getToscaResourceName());
-			filteredResource.setResourceType(resource.getResourceType());
-		} else if (componentTypeEnum == ComponentTypeEnum.SERVICE) {
-			Service service = (Service) component;
-			Service filteredService = (Service) filteredComponent;
-			filteredService.setDistributionStatus(service.getDistributionStatus());
-		}
-	}
+        return result;
+    }
 
-	/**
-	 * get components from cache of a given list ou unique ids.
-	 *
-	 * for each component data from cassandra, unzip the data if needed and
-	 * deserialize the unzipped data to java object(Component).
-	 *
-	 * @param filteredResources
-	 * @return ImmutableTripple or ActionStatus. | |-- components |-- dirty
-	 *         components - components with dirty flag = true. |-- set of non cached
-	 *         components
-	 *
-	 */
-	private Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsFull(
-			Set<String> filteredResources) {
+    private Component filterFieldsForCatalog(Component component) {
 
-		if (false == isEnabled()) {
-			logger.debug("Component Cache is disabled");
-			return Either.right(ActionStatus.NOT_ALLOWED);
-		}
+        Component result = null;
+        ComponentTypeEnum componentTypeEnum = component.getComponentType();
+        switch (componentTypeEnum) {
+        case RESOURCE:
+            result = new Resource();
+            copyFieldsForCatalog(component, result);
+            break;
+        case SERVICE:
+            result = new Service();
+            copyFieldsForCatalog(component, result);
+            break;
+        case PRODUCT:
+            result = new Product();
+            copyFieldsForCatalog(component, result);
+            break;
+        default:
+            break;
+        }
 
-		List<Component> foundResources = new LinkedList<>();
-		List<Component> foundDirtyResources = new LinkedList<>();
-		Set<String> notFoundResources = new HashSet<>();
-		ImmutableTriple<List<Component>, List<Component>, Set<String>> result = new ImmutableTriple<List<Component>, List<Component>, Set<String>>(
-				foundResources, foundDirtyResources, notFoundResources);
+        return result;
+    }
 
-		long cassandraFetchStart = System.currentTimeMillis();
-		List<String> uidsList = new ArrayList<>();
-		uidsList.addAll(filteredResources);
-		Either<List<ComponentCacheData>, ActionStatus> componentsFromCache = componentCassandraDao
-				.getComponents(uidsList);
+    /**
+     * Copy relevant fields to the filtered component for left panel
+     *
+     * @param component
+     * @param filteredComponent
+     */
+    private void copyFieldsForLeftPanel(Component component, Component filteredComponent) {
 
-		long cassandraFetchEnd = System.currentTimeMillis();
-		logger.debug("Fetch time from cassandara of all components took {} ms",
-				(cassandraFetchEnd - cassandraFetchStart));
-		if (componentsFromCache.isRight()) {
-			BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache",
-					"Failed to fetch components from cache", ErrorSeverity.ERROR);
-			return Either.right(componentsFromCache.right().value());
-		}
+        ComponentTypeEnum componentTypeEnum = component.getComponentType();
+        filteredComponent.setCategories(component.getCategories());
+        filteredComponent.setComponentType(component.getComponentType());
+        if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType())
+                && ResourceTypeEnum.VL.equals(((ResourceMetadataDataDefinition) component
+                        .getComponentMetadataDefinition().getMetadataDataDefinition()).getResourceType())) {
+            filteredComponent.setCapabilities(component.getCapabilities());
+            filteredComponent.setRequirements(component.getRequirements());
+        }
+        filteredComponent.setVersion(component.getVersion());
+        filteredComponent.setDescription(component.getDescription());
+        filteredComponent.setUniqueId(component.getUniqueId());
+        filteredComponent.setIcon(component.getIcon());
+        filteredComponent.setTags(component.getTags());
+        filteredComponent.setLifecycleState(component.getLifecycleState());
+        filteredComponent.setInvariantUUID(component.getInvariantUUID());
+        filteredComponent.setUUID(component.getUUID());
+        filteredComponent.setSystemName(component.getSystemName());
+        filteredComponent.setName(component.getName());
 
-		List<ComponentCacheData> list = componentsFromCache.left().value();
-		logger.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size()));
-		if (list != null && false == list.isEmpty()) {
+        if (componentTypeEnum == ComponentTypeEnum.RESOURCE) {
+            Resource resource = (Resource) component;
+            Resource filteredResource = (Resource) filteredComponent;
+            filteredResource.setToscaResourceName(resource.getToscaResourceName());
+            filteredResource.setResourceType(resource.getResourceType());
+        }
+    }
 
-			List<ComponentCacheData> filteredData = list.stream().filter(p -> filteredResources.contains(p.getId()))
-					.collect(Collectors.toList());
-			logger.debug("Number of components filterd is {}", filteredData == null ? 0 : filteredData.size());
+    private void copyFieldsForCatalog(Component component, Component filteredComponent) {
 
-			if (filteredData != null) {
-				long desStart = System.currentTimeMillis();
+        ComponentTypeEnum componentTypeEnum = component.getComponentType();
+        filteredComponent.setCategories(component.getCategories());
+        filteredComponent.setComponentType(component.getComponentType());
+        filteredComponent.setVersion(component.getVersion());
+        filteredComponent.setDescription(component.getDescription());
+        filteredComponent.setUniqueId(component.getUniqueId());
+        filteredComponent.setIcon(component.getIcon());
+        filteredComponent.setTags(component.getTags());
+        filteredComponent.setLifecycleState(component.getLifecycleState());
+        filteredComponent.setSystemName(component.getSystemName());
+        filteredComponent.setName(component.getName());
+        filteredComponent.setLastUpdateDate(component.getLastUpdateDate());
 
-				for (ComponentCacheData componentCacheData : filteredData) {
+        if (componentTypeEnum == ComponentTypeEnum.RESOURCE) {
+            Resource resource = (Resource) component;
+            Resource filteredResource = (Resource) filteredComponent;
+            filteredResource.setToscaResourceName(resource.getToscaResourceName());
+            filteredResource.setResourceType(resource.getResourceType());
+        } else if (componentTypeEnum == ComponentTypeEnum.SERVICE) {
+            Service service = (Service) component;
+            Service filteredService = (Service) filteredComponent;
+            filteredService.setDistributionStatus(service.getDistributionStatus());
+        }
+    }
 
-					logger.debug("Process uid {} from cache", componentCacheData.getId());
+    /**
+     * get components from cache of a given list ou unique ids.
+     *
+     * for each component data from cassandra, unzip the data if needed and
+     * deserialize the unzipped data to java object(Component).
+     *
+     * @param filteredResources
+     * @return ImmutableTripple or ActionStatus. | |-- components |-- dirty
+     *         components - components with dirty flag = true. |-- set of non
+     *         cached components
+     *
+     */
+    private Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsFull(
+            Set<String> filteredResources) {
 
-					String compUid = componentCacheData.getId();
+        if (!isEnabled()) {
+            log.debug(COMPONENT_CACHE_IS_DISABLED);
+            return Either.right(ActionStatus.NOT_ALLOWED);
+        }
 
-					Either<? extends Component, Boolean> deserializeExt = convertComponentCacheToComponent(
-							componentCacheData);
+        List<Component> foundResources = new LinkedList<>();
+        List<Component> foundDirtyResources = new LinkedList<>();
+        Set<String> notFoundResources = new HashSet<>();
+        ImmutableTriple<List<Component>, List<Component>, Set<String>> result = new ImmutableTriple<>(
+                foundResources, foundDirtyResources, notFoundResources);
 
-					if (deserializeExt.isLeft()) {
-						Component component = deserializeExt.left().value();
-						if (false == componentCacheData.getIsDirty()) {
-							foundResources.add(component);
-						} else {
-							foundDirtyResources.add(component);
-						}
-					} else {
-						notFoundResources.add(compUid);
-					}
+        long cassandraFetchStart = System.currentTimeMillis();
+        List<String> uidsList = new ArrayList<>();
+        uidsList.addAll(filteredResources);
+        Either<List<ComponentCacheData>, ActionStatus> componentsFromCache = componentCassandraDao
+                .getComponents(uidsList);
 
-				}
-				long desEnd = System.currentTimeMillis();
-				logger.debug("Deserialization and unzip of {} components took {} ms", filteredData.size(),
-						(desEnd - desStart));
-			}
-		}
-		List<String> foundResourcesUid = foundResources.stream().map(p -> p.getUniqueId()).collect(Collectors.toList());
-		List<String> foundDirtyResourcesUid = foundDirtyResources.stream().map(p -> p.getUniqueId())
-				.collect(Collectors.toList());
-		logger.debug("Number of processed components from cache is {}",
-				(foundResourcesUid.size() + foundDirtyResourcesUid.size()));
-		Set<String> notCachedResources = filteredResources.stream()
-				.filter(p -> false == foundResourcesUid.contains(p) && false == foundDirtyResourcesUid.contains(p))
-				.collect(Collectors.toSet());
-		notFoundResources.addAll(notCachedResources);
+        long cassandraFetchEnd = System.currentTimeMillis();
+        log.debug("Fetch time from cassandara of all components took {} ms",
+                (cassandraFetchEnd - cassandraFetchStart));
+        if (componentsFromCache.isRight()) {
+            BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache",
+                    "Failed to fetch components from cache", ErrorSeverity.ERROR);
+            return Either.right(componentsFromCache.right().value());
+        }
+
+        List<ComponentCacheData> list = componentsFromCache.left().value();
+        log.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size()));
+        if (list != null && !list.isEmpty()) {
 
-		logger.debug("Number of components fetched is {}", foundResources.size());
-		logger.debug("Number of components fetched dirty is {}", foundDirtyResources.size());
-		logger.debug("Number of components non cached is {}", notCachedResources.size());
+            List<ComponentCacheData> filteredData = list.stream().filter(p -> filteredResources.contains(p.getId()))
+                    .collect(Collectors.toList());
+            log.debug("Number of components filterd is {}", filteredData == null ? 0 : filteredData.size());
 
-		return Either.left(result);
-	}
+            if (filteredData != null) {
+                long desStart = System.currentTimeMillis();
 
-	private Either<? extends Component, Boolean> convertComponentCacheToComponent(
-			ComponentCacheData componentCacheData) {
+                for (ComponentCacheData componentCacheData : filteredData) {
 
-		String compUid = componentCacheData.getId();
+                    log.debug("Process uid {} from cache", componentCacheData.getId());
 
-		byte[] dataAsArray = componentCacheData.getDataAsArray();
+                    String compUid = componentCacheData.getId();
 
-		if (true == componentCacheData.getIsZipped()) {
-			long startUnzip = System.nanoTime();
-			dataAsArray = ZipUtil.unzip(dataAsArray);
-			long endUnzip = System.nanoTime();
-			logger.trace("Unzip component {} took {} microsecond", compUid, (endUnzip - startUnzip) / 1000);
-		}
+                    Either<? extends Component, Boolean> deserializeExt = convertComponentCacheToComponent(
+                            componentCacheData);
 
-		long startDes = System.nanoTime();
+                    if (deserializeExt.isLeft()) {
+                        Component component = deserializeExt.left().value();
+                        if (!componentCacheData.getIsDirty()) {
+                            foundResources.add(component);
+                        } else {
+                            foundDirtyResources.add(component);
+                        }
+                    } else {
+                        notFoundResources.add(compUid);
+                    }
 
-		Either<? extends Component, Boolean> deserializeExt = deserializeComponent(componentCacheData, dataAsArray);
+                }
+                long desEnd = System.currentTimeMillis();
+                log.debug("Deserialization and unzip of {} components took {} ms", filteredData.size(),
+                        (desEnd - desStart));
+            }
+        }
+        List<String> foundResourcesUid = foundResources.stream().map(Component::getUniqueId).collect(Collectors.toList());
+        List<String> foundDirtyResourcesUid = foundDirtyResources.stream().map(Component::getUniqueId)
+                .collect(Collectors.toList());
+        log.debug("Number of processed components from cache is {}",
+                (foundResourcesUid.size() + foundDirtyResourcesUid.size()));
+        Set<String> notCachedResources = filteredResources.stream()
+                .filter(p -> !foundResourcesUid.contains(p) && !foundDirtyResourcesUid.contains(p))
+                .collect(Collectors.toSet());
+        notFoundResources.addAll(notCachedResources);
 
-		long endDes = System.nanoTime();
-		logger.trace("Deserialize component {} took {} microsecond", compUid, (endDes - startDes) / 1000);
-		return deserializeExt;
-	}
+        if (log.isDebugEnabled()) {
+            log.debug("Number of components fetched is {}", foundResources.size());
+            log.debug("Number of components fetched dirty is {}", foundDirtyResources.size());
+            log.debug("Number of components non cached is {}", notCachedResources.size());
+        }
 
-	private Either<? extends Component, Boolean> deserializeComponent(ComponentCacheData componentCacheData,
-			byte[] dataAsArray) {
-		String type = componentCacheData.getType();
-		NodeTypeEnum typeEnum = NodeTypeEnum.getByNameIgnoreCase(type);
+        return Either.left(result);
+    }
 
-		Either<? extends Component, Boolean> deserializeExt = Either.right(false);
-		switch (typeEnum) {
-		case Resource:
-			deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Resource.class, componentCacheData.getId());
-			break;
-		case Service:
-			deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Service.class, componentCacheData.getId());
-			break;
-		case Product:
-			deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Product.class, componentCacheData.getId());
-			break;
-		default:
-			break;
-		}
-		return deserializeExt;
-	}
+    private Either<? extends Component, Boolean> convertComponentCacheToComponent(
+            ComponentCacheData componentCacheData) {
 
-	public Either<Component, ActionStatus> getComponent(String componentUid) {
+        String compUid = componentCacheData.getId();
 
-		return getComponent(componentUid, null, Function.identity());
-	}
+        byte[] dataAsArray = componentCacheData.getDataAsArray();
 
-	public Either<Component, ActionStatus> getComponent(String componentUid, Long lastModificationTime) {
+        if (componentCacheData.getIsZipped()) {
+            long startUnzip = System.nanoTime();
+            dataAsArray = ZipUtil.unzip(dataAsArray);
+            long endUnzip = System.nanoTime();
+            log.trace("Unzip component {} took {} microsecond", compUid, (endUnzip - startUnzip) / 1000);
+        }
 
-		return getComponent(componentUid, lastModificationTime, Function.identity());
+        long startDes = System.nanoTime();
 
-	}
+        Either<? extends Component, Boolean> deserializeExt = deserializeComponent(componentCacheData, dataAsArray);
 
-	public boolean setComponent(String componentUid, Long lastModificationTime, NodeTypeEnum nodeTypeEnum) {
+        long endDes = System.nanoTime();
+        log.trace("Deserialize component {} took {} microsecond", compUid, (endDes - startDes) / 1000);
+        return deserializeExt;
+    }
 
-		boolean result = false;
+    private Either<? extends Component, Boolean> deserializeComponent(ComponentCacheData componentCacheData,
+            byte[] dataAsArray) {
+        String type = componentCacheData.getType();
+        NodeTypeEnum typeEnum = NodeTypeEnum.getByNameIgnoreCase(type);
 
-		if (false == isEnabled()) {
-			logger.debug("Component Cache is disabled");
-			return false;
-		}
+        Either<? extends Component, Boolean> deserializeExt = Either.right(false);
+        switch (typeEnum) {
+        case Resource:
+            deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Resource.class, componentCacheData.getId());
+            break;
+        case Service:
+            deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Service.class, componentCacheData.getId());
+            break;
+        case Product:
+            deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Product.class, componentCacheData.getId());
+            break;
+        default:
+            break;
+        }
+        return deserializeExt;
+    }
 
-		Either<Component, StorageOperationStatus> either = toscaOperationFacade.getToscaElement(componentUid);
-		if (either.isLeft()) {
-			Component component = either.left().value();
-			result = saveComponent(componentUid, lastModificationTime, nodeTypeEnum, component);
-		} else {
-			logger.debug("Failed to get component {} of type {} from graph. Status is {}", componentUid,
-					nodeTypeEnum.name().toLowerCase(), either.right().value());
-		}
+    public Either<Component, ActionStatus> getComponent(String componentUid) {
 
-		return result;
+        return getComponent(componentUid, null, Function.identity());
 
-	}
+    }
 
-	private boolean saveComponent(String componentUid, Long lastModificationTime, NodeTypeEnum nodeTypeEnum,
-			Component component) {
+    private boolean saveComponent(String componentUid, Long lastModificationTime, NodeTypeEnum nodeTypeEnum,
+            Component component) {
 
-		logger.trace("Going to save component {} of type {} in cache", componentUid, nodeTypeEnum.name().toLowerCase());
+        log.trace("Going to save component {} of type {} in cache", componentUid, nodeTypeEnum.name().toLowerCase());
 
-		boolean result = false;
+        boolean result = false;
 
-		Either<byte[], Boolean> serializeExt = SerializationUtils.serializeExt(component);
-		if (serializeExt.isLeft()) {
-			byte[] serializedData = serializeExt.left().value();
-			byte[] zipBytes;
-			try {
-				zipBytes = ZipUtil.zipBytes(serializedData);
-				ComponentCacheData componentCacheData = new ComponentCacheData();
-				componentCacheData.setDataAsArray(zipBytes);
-				componentCacheData.setIsZipped(true);
-				componentCacheData.setId(componentUid);
-				componentCacheData.setModificationTime(new Date(lastModificationTime));
-				componentCacheData.setType(component.getComponentType().name().toLowerCase());
+        Either<byte[], Boolean> serializeExt = SerializationUtils.serializeExt(component);
+        if (serializeExt.isLeft()) {
+            byte[] serializedData = serializeExt.left().value();
+            byte[] zipBytes;
+            try {
+                zipBytes = ZipUtil.zipBytes(serializedData);
+                ComponentCacheData componentCacheData = new ComponentCacheData();
+                componentCacheData.setDataAsArray(zipBytes);
+                componentCacheData.setIsZipped(true);
+                componentCacheData.setId(componentUid);
+                componentCacheData.setModificationTime(new Date(lastModificationTime));
+                componentCacheData.setType(component.getComponentType().name().toLowerCase());
 
-				CassandraOperationStatus status = componentCassandraDao.saveComponent(componentCacheData);
+                CassandraOperationStatus status = componentCassandraDao.saveComponent(componentCacheData);
 
-				if (status == CassandraOperationStatus.OK) {
-					result = true;
-				}
+                if (status == CassandraOperationStatus.OK) {
+                    result = true;
+                }
 
-			} catch (IOException e) {
-				logger.debug("Failed to prepare component {} of type {} for cache", componentUid,
-						nodeTypeEnum.name().toLowerCase());
-			}
-		} else {
-			logger.debug("Failed to serialize component {} of type {} for cache", componentUid,
-					nodeTypeEnum.name().toLowerCase());
-		}
-		return result;
-	}
+            } catch (IOException e) {
+                log.debug("Failed to prepare component {} of type {} for cache", componentUid,
+                        nodeTypeEnum.name().toLowerCase());
+                if (log.isTraceEnabled()) {
+                    log.trace("Failed to prepare component {} of type {} for cache",componentUid,nodeTypeEnum.name().toLowerCase());
+                }
+            }
+        } else {
+            log.debug("Failed to serialize component {} of type {} for cache", componentUid,
+                    nodeTypeEnum.name().toLowerCase());
+        }
+        return result;
+    }
 
-	public boolean setComponent(Component component, NodeTypeEnum nodeTypeEnum) {
+    public boolean setComponent(Component component, NodeTypeEnum nodeTypeEnum) {
 
-		boolean result = false;
+        boolean result = false;
 
-		if (false == isEnabled()) {
-			logger.debug("Component Cache is disabled");
-			return false;
-		}
+        if (!isEnabled()) {
+            log.debug(COMPONENT_CACHE_IS_DISABLED);
+            return false;
+        }
 
-		String componentUid = component.getUniqueId();
-		Long lastUpdateDate = component.getLastUpdateDate();
+        String componentUid = component.getUniqueId();
+        Long lastUpdateDate = component.getLastUpdateDate();
 
-		result = saveComponent(componentUid, lastUpdateDate, nodeTypeEnum, component);
+        result = saveComponent(componentUid, lastUpdateDate, nodeTypeEnum, component);
 
-		return result;
+        return result;
 
-	}
+    }
 
-	/**
-	 * get components from cache of a given list ou unique ids.
-	 * 
-	 * for each component data from cassandra, unzip the data if needed and
-	 * deserialize the unzipped data to java object(Component).
-	 * 
-	 * @param filteredResources
-	 * @return ImmutableTripple or ActionStatus. | |-- components |-- set of non
-	 *         cached components
-	 * 
-	 */
-	private Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsFull(
-			Map<String, Long> filteredResources) {
+    /**
+     * get components from cache of a given list ou unique ids.
+     *
+     * for each component data from cassandra, unzip the data if needed and
+     * deserialize the unzipped data to java object(Component).
+     *
+     * @param filteredResources
+     * @return ImmutableTripple or ActionStatus. | |-- components |-- set of non
+     *         cached components
+     *
+     */
+    private Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsFull(
+            Map<String, Long> filteredResources) {
 
-		if (false == isEnabled()) {
-			logger.debug("Component Cache is disabled");
-			return Either.right(ActionStatus.NOT_ALLOWED);
-		}
+        if (!isEnabled()) {
+            log.debug(COMPONENT_CACHE_IS_DISABLED);
+            return Either.right(ActionStatus.NOT_ALLOWED);
+        }
 
-		List<Component> foundResources = new LinkedList<>();
-		Set<String> notFoundResources = new HashSet<>();
-		ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<List<Component>, Set<String>>(
-				foundResources, notFoundResources);
+        List<Component> foundResources = new LinkedList<>();
+        Set<String> notFoundResources = new HashSet<>();
+        ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<>(
+                foundResources, notFoundResources);
 
-		long cassandraFetchStart = System.currentTimeMillis();
+        long cassandraFetchStart = System.currentTimeMillis();
 
-		Either<ImmutablePair<List<ComponentCacheData>, Set<String>>, ActionStatus> componentsFromCache = componentCassandraDao
-				.getComponents(filteredResources);
+        Either<ImmutablePair<List<ComponentCacheData>, Set<String>>, ActionStatus> componentsFromCache = componentCassandraDao
+                .getComponents(filteredResources);
 
-		long cassandraFetchEnd = System.currentTimeMillis();
-		logger.debug("Fetch time from cassandara of all components took {} ms",
-				(cassandraFetchEnd - cassandraFetchStart));
-		if (componentsFromCache.isRight()) {
-			BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache",
-					"Failed to fetch components from cache", ErrorSeverity.ERROR);
-			return Either.right(componentsFromCache.right().value());
-		}
+        long cassandraFetchEnd = System.currentTimeMillis();
+        log.debug("Fetch time from cassandara of all components took {} ms",
+                (cassandraFetchEnd - cassandraFetchStart));
+        if (componentsFromCache.isRight()) {
+            BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache",
+                    "Failed to fetch components from cache", ErrorSeverity.ERROR);
+            return Either.right(componentsFromCache.right().value());
+        }
 
-		ImmutablePair<List<ComponentCacheData>, Set<String>> immutablePair = componentsFromCache.left().value();
-		List<ComponentCacheData> list = immutablePair.getLeft();
-		logger.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size()));
-		if (list != null && false == list.isEmpty()) {
+        ImmutablePair<List<ComponentCacheData>, Set<String>> immutablePair = componentsFromCache.left().value();
+        List<ComponentCacheData> list = immutablePair.getLeft();
+        log.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size()));
+        if (list != null && !list.isEmpty()) {
 
-			// List<ComponentCacheData> filteredData = list.stream().filter(p ->
-			// filteredResources.contains(p.getId())).collect(Collectors.toList());
-			logger.debug("Number of components filterd is {}", list == null ? 0 : list.size());
+            log.debug("Number of components filterd is {}", list == null ? 0 : list.size());
 
-			if (list != null) {
-				long desStart = System.currentTimeMillis();
+            if (list != null) {
+                long desStart = System.currentTimeMillis();
 
-				for (ComponentCacheData componentCacheData : list) {
+                for (ComponentCacheData componentCacheData : list) {
 
-					logger.debug("Process uid {} from cache", componentCacheData.getId());
+                    log.debug("Process uid {} from cache", componentCacheData.getId());
 
-					String compUid = componentCacheData.getId();
+                    String compUid = componentCacheData.getId();
 
-					Either<? extends Component, Boolean> deserializeExt = convertComponentCacheToComponent(
-							componentCacheData);
+                    Either<? extends Component, Boolean> deserializeExt = convertComponentCacheToComponent(
+                            componentCacheData);
 
-					if (deserializeExt.isLeft()) {
-						Component component = deserializeExt.left().value();
-						foundResources.add(component);
-					} else {
-						notFoundResources.add(compUid);
-					}
+                    if (deserializeExt.isLeft()) {
+                        Component component = deserializeExt.left().value();
+                        foundResources.add(component);
+                    } else {
+                        notFoundResources.add(compUid);
+                    }
 
-				}
-				long desEnd = System.currentTimeMillis();
-				logger.debug("Deserialization and unzip of {} components took {} ms", list.size(), (desEnd - desStart));
-			}
-		}
-		logger.debug("Number of processed components from cache is {}", foundResources.size());
+                }
+                long desEnd = System.currentTimeMillis();
+                log.debug("Deserialization and unzip of {} components took {} ms", list.size(), (desEnd - desStart));
+            }
+        }
+        log.debug("Number of processed components from cache is {}", foundResources.size());
 
-		Set<String> notFoundInCache = immutablePair.getRight();
-		notFoundResources.addAll(notFoundInCache);
+        Set<String> notFoundInCache = immutablePair.getRight();
+        notFoundResources.addAll(notFoundInCache);
 
-		logger.debug("Number of components fetched is {}", foundResources.size());
-		logger.debug("Number of components non cached is {}", notFoundResources.size());
+        if (log.isDebugEnabled()) {
+            log.debug("Number of components fetched is {}", foundResources.size());
+            log.debug("Number of components non cached is {}", notFoundResources.size());
+        }
 
-		return Either.left(result);
-	}
+        return Either.left(result);
+    }
 
-	/**
-	 * get components for catalog
-	 * 
-	 * @param components
-	 * @param componentTypeEnum
-	 * @return
-	 */
-	public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsForCatalog(
-			Map<String, Long> components, ComponentTypeEnum componentTypeEnum) {
+    /**
+     * get components for catalog
+     *
+     * @param components
+     * @param componentTypeEnum
+     * @return
+     */
+    public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsForCatalog(
+            Map<String, Long> components, ComponentTypeEnum componentTypeEnum) {
 
-		if (false == isEnabled()) {
-			logger.debug("In getComponentsForCatalog for type {}. Cache is disabled.",
-					componentTypeEnum.name().toLowerCase());
-			return Either.right(ActionStatus.NOT_ALLOWED);
-		}
-		logger.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase());
+        if (!isEnabled()) {
+            log.debug("In getComponentsForCatalog for type {}. Cache is disabled.",
+                    componentTypeEnum.name().toLowerCase());
+            return Either.right(ActionStatus.NOT_ALLOWED);
+        }
+        log.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase());
 
-		Function<List<Component>, List<Component>> filterFieldsFunc = x -> filterForCatalog(x);
+        Function<List<Component>, List<Component>> filterFieldsFunc = this::filterForCatalog;
 
-		Map<String, Long> leftComponentsForSearch = new HashMap<>();
-		leftComponentsForSearch.putAll(components);
+        Map<String, Long> leftComponentsForSearch = new HashMap<>();
+        leftComponentsForSearch.putAll(components);
 
-		// get components from inmemory cache
-		List<Component> componentsFromMemory = null;
-		if (true == catalogInMemoryEnabled) {
-			componentsFromMemory = getDataFromInMemoryCache(components.keySet(), componentTypeEnum);
-			logger.debug("The number of components of type {} fetched from memory is {}",
-					componentTypeEnum.name().toLowerCase(),
-					componentsFromMemory == null ? 0 : componentsFromMemory.size());
-			if (componentsFromMemory != null) {
-				List<String> ignoredComponents = new ArrayList<>();
-				for (Component componentFromMem : componentsFromMemory) {
-					if (componentFromMem.getLastUpdateDate().longValue() != components
-							.get(componentFromMem.getUniqueId()).longValue()) {
-						// Ignore the component from memory
-						ignoredComponents.add(componentFromMem.getUniqueId());
-					}
-				}
+        // get components from inmemory cache
+        List<Component> componentsFromMemory = null;
+        if (catalogInMemoryEnabled) {
+            componentsFromMemory = getDataFromInMemoryCache(components.keySet(), componentTypeEnum);
+            log.debug("The number of components of type {} fetched from memory is {}",
+                    componentTypeEnum.name().toLowerCase(),
+                    componentsFromMemory == null ? 0 : componentsFromMemory.size());
+            if (componentsFromMemory != null) {
+                List<String> ignoredComponents = new ArrayList<>();
+                for (Component componentFromMem : componentsFromMemory) {
+                    if (componentFromMem.getLastUpdateDate().longValue() != components
+                            .get(componentFromMem.getUniqueId()).longValue()) {
+                        // Ignore the component from memory
+                        ignoredComponents.add(componentFromMem.getUniqueId());
+                    }
+                }
 
-				logger.debug("Number of components from type {} ignored from memory cache is {}",
-						componentTypeEnum.name().toLowerCase(), ignoredComponents.size());
-				// remove from memory result the components which are not valid
-				componentsFromMemory = componentsFromMemory.stream()
-						.filter(p -> false == ignoredComponents.contains(p.getUniqueId())).collect(Collectors.toList());
-				// Remove from leftComponentsForSearch the valid components from
-				// memory
-				componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId()));
+                log.debug("Number of components from type {} ignored from memory cache is {}",
+                        componentTypeEnum.name().toLowerCase(), ignoredComponents.size());
+                // remove from memory result the components which are not valid
+                componentsFromMemory = componentsFromMemory.stream()
+                                                           .filter(p -> !ignoredComponents.contains(p.getUniqueId())).collect(Collectors.toList());
+                // Remove from leftComponentsForSearch the valid components from
+                // memory
+                componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId()));
 
-			}
-		} else {
-			logger.debug("Catalog InMemory cache is disabled");
-		}
+            }
+        } else {
+            log.debug("Catalog InMemory cache is disabled");
+        }
 
-		logger.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(),
-				leftComponentsForSearch.size());
+        log.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(),
+                leftComponentsForSearch.size());
 
-		// get components from cassandra cache and filter each component
-		Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result = getComponents(
-				leftComponentsForSearch, filterFieldsFunc);
+        // get components from cassandra cache and filter each component
+        Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result = getComponents(
+                leftComponentsForSearch, filterFieldsFunc);
 
-		if (result.isLeft()) {
-			// add inmemory components to the valid components(not dirty)
-			List<Component> foundComponents = result.left().value().getLeft();
-			if (componentsFromMemory != null) {
-				foundComponents.addAll(componentsFromMemory);
-			}
-			if (true == catalogInMemoryEnabled) {
-				updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum);
-			}
-		}
+        if (result.isLeft()) {
+            // add inmemory components to the valid components(not dirty)
+            List<Component> foundComponents = result.left().value().getLeft();
+            if (componentsFromMemory != null) {
+                foundComponents.addAll(componentsFromMemory);
+            }
+            if (catalogInMemoryEnabled) {
+                updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum);
+            }
+        }
 
-		return result;
-	}
+        return result;
+    }
 
-	/**
-	 * @param components
-	 *            - Map of <componentUniqueId, last update date>
-	 * @param filterFieldsFunc
-	 * @return
-	 */
-	public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponents(Map<String, Long> components,
-			Function<List<Component>, List<Component>> filterFieldsFunc) {
+    /**
+     * @param components
+     *            - Map of <componentUniqueId, last update date>
+     * @param filterFieldsFunc
+     * @return
+     */
+    public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponents(Map<String, Long> components,
+            Function<List<Component>, List<Component>> filterFieldsFunc) {
 
-		if (false == isEnabled()) {
-			logger.debug("Component Cache is disabled");
-			return Either.right(ActionStatus.NOT_ALLOWED);
-		}
+        if (!isEnabled()) {
+            log.debug(COMPONENT_CACHE_IS_DISABLED);
+            return Either.right(ActionStatus.NOT_ALLOWED);
+        }
 
-		Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> componentsFull = getComponentsFull(
-				components);
+        Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> componentsFull = getComponentsFull(
+                components);
 
-		if (componentsFull.isRight()) {
-			return Either.right(componentsFull.right().value());
-		}
+        if (componentsFull.isRight()) {
+            return Either.right(componentsFull.right().value());
+        }
 
-		ImmutablePair<List<Component>, Set<String>> immutablePair = componentsFull.left().value();
-		List<Component> foundResources = immutablePair.left;
-		Set<String> notFoundResources = immutablePair.right;
+        ImmutablePair<List<Component>, Set<String>> immutablePair = componentsFull.left().value();
+        List<Component> foundResources = immutablePair.left;
+        Set<String> notFoundResources = immutablePair.right;
 
-		List<Component> filterdFoundResources = filterFieldsFunc.apply(foundResources);
+        List<Component> filterdFoundResources = filterFieldsFunc.apply(foundResources);
 
-		ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<List<Component>, Set<String>>(
-				filterdFoundResources, notFoundResources);
+        ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<>(
+                filterdFoundResources, notFoundResources);
 
-		return Either.left(result);
+        return Either.left(result);
 
-	}
+    }
 
-	/**
-	 * get the component and its modification time from cache
-	 * 
-	 * @param componentUid
-	 * @param filterFieldsFunc
-	 * @return
-	 */
-	public Either<ImmutablePair<Component, Long>, ActionStatus> getComponentAndTime(String componentUid,
-			Function<Component, Component> filterFieldsFunc) {
+    /**
+     * get the component and its modification time from cache
+     *
+     * @param componentUid
+     * @param filterFieldsFunc
+     * @return
+     */
+    public Either<ImmutablePair<Component, Long>, ActionStatus> getComponentAndTime(String componentUid,
+            Function<Component, Component> filterFieldsFunc) {
 
-		Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> componentFromCache = getComponentFromCache(
-				componentUid, null, filterFieldsFunc);
+        Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> componentFromCache = getComponentFromCache(
+                componentUid, null, filterFieldsFunc);
 
-		if (componentFromCache.isRight()) {
-			return Either.right(componentFromCache.right().value());
-		}
+        if (componentFromCache.isRight()) {
+            return Either.right(componentFromCache.right().value());
+        }
 
-		ImmutablePair<Component, ComponentCacheData> immutablePair = componentFromCache.left().value();
+        ImmutablePair<Component, ComponentCacheData> immutablePair = componentFromCache.left().value();
 
-		ImmutablePair<Component, Long> result = new ImmutablePair<Component, Long>(immutablePair.left,
-				immutablePair.right.getModificationTime().getTime());
+        ImmutablePair<Component, Long> result = new ImmutablePair<>(immutablePair.left,
+                immutablePair.right.getModificationTime().getTime());
 
-		return Either.left(result);
-	}
+        return Either.left(result);
+    }
 
-	private Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> getComponentFromCache(
-			String componentUid, Long lastModificationTime, Function<Component, Component> filterFieldsFunc) {
-		if (false == isEnabled()) {
-			return Either.right(ActionStatus.NOT_ALLOWED);
-		}
+    private Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> getComponentFromCache(
+            String componentUid, Long lastModificationTime, Function<Component, Component> filterFieldsFunc) {
+        if (!isEnabled()) {
+            return Either.right(ActionStatus.NOT_ALLOWED);
+        }
 
-		Either<ComponentCacheData, ActionStatus> componentRes = componentCassandraDao.getComponent(componentUid);
+        Either<ComponentCacheData, ActionStatus> componentRes = componentCassandraDao.getComponent(componentUid);
 
-		if (componentRes.isRight()) {
-			return Either.right(componentRes.right().value());
-		}
+        if (componentRes.isRight()) {
+            return Either.right(componentRes.right().value());
+        }
 
-		ComponentCacheData componentCacheData = componentRes.left().value();
+        ComponentCacheData componentCacheData = componentRes.left().value();
 
-		if (lastModificationTime != null) {
-			long cacheCompModificationTime = componentCacheData.getModificationTime().getTime();
-			if (lastModificationTime != cacheCompModificationTime) {
-				logger.debug(
-						"Component {} found in cache but its modification time {} does not match to the timestamp in cache {}.",
-						componentUid, lastModificationTime, cacheCompModificationTime);
-				return Either.right(ActionStatus.INVALID_CONTENT);
-			}
-		}
+        if (lastModificationTime != null) {
+            long cacheCompModificationTime = componentCacheData.getModificationTime().getTime();
+            if (lastModificationTime != cacheCompModificationTime) {
+                log.debug(
+                        "Component {} found in cache but its modification time {} does not match to the timestamp in cache {}.",
+                        componentUid, lastModificationTime, cacheCompModificationTime);
+                return Either.right(ActionStatus.INVALID_CONTENT);
+            }
+        }
 
-		Either<? extends Component, Boolean> convertRes = convertComponentCacheToComponent(componentCacheData);
-		if (convertRes.isRight()) {
-			return Either.right(ActionStatus.CONVERT_COMPONENT_ERROR);
-		}
+        Either<? extends Component, Boolean> convertRes = convertComponentCacheToComponent(componentCacheData);
+        if (convertRes.isRight()) {
+            return Either.right(ActionStatus.CONVERT_COMPONENT_ERROR);
+        }
 
-		Component component = convertRes.left().value();
+        Component component = convertRes.left().value();
 
-		Component filteredComponent = component;
-		if (filterFieldsFunc != null) {
-			filteredComponent = filterFieldsFunc.apply(component);
-		}
+        Component filteredComponent = component;
+        if (filterFieldsFunc != null) {
+            filteredComponent = filterFieldsFunc.apply(component);
+        }
 
-		ImmutablePair<Component, ComponentCacheData> result = new ImmutablePair<Component, ComponentCacheData>(
-				filteredComponent, componentCacheData);
+        ImmutablePair<Component, ComponentCacheData> result = new ImmutablePair<>(
+                filteredComponent, componentCacheData);
 
-		return Either.left(result);
-	}
+        return Either.left(result);
+    }
 
-	public ActionStatus deleteComponentFromCache(String id) {
-		if (false == isEnabled()) {
-			return ActionStatus.NOT_ALLOWED;
-		}
-		CassandraOperationStatus status = componentCassandraDao.deleteComponent(id);
-		if (CassandraOperationStatus.OK.equals(status)) {
-			return ActionStatus.OK;
-		} else {
-			logger.debug("delete component failed with error {}", status);
-			return ActionStatus.GENERAL_ERROR;
-		}
-	}
+    public ActionStatus deleteComponentFromCache(String id) {
+        if (!isEnabled()) {
+            return ActionStatus.NOT_ALLOWED;
+        }
+        CassandraOperationStatus status = this.componentCassandraDao.deleteComponent(id);
+        if (CassandraOperationStatus.OK.equals(status)) {
+            return ActionStatus.OK;
+        } else {
+            log.debug("delete component failed with error {}", status);
+            return ActionStatus.GENERAL_ERROR;
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.java
index c7bcc54..4880afe 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.java
@@ -23,19 +23,19 @@
 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
 
 public class DaoInfo {
-	private ToscaOperationFacade toscaOperationFacade;
-	private ComponentCache ComponentCache;
+    private ToscaOperationFacade toscaOperationFacade;
+    private ComponentCache ComponentCache;
 
-	public DaoInfo(ToscaOperationFacade toscaOperationFacade, org.openecomp.sdc.be.model.cache.ComponentCache componentCache) {
-		this.toscaOperationFacade = toscaOperationFacade;
-		ComponentCache = componentCache;
-	}
+    public DaoInfo(ToscaOperationFacade toscaOperationFacade, org.openecomp.sdc.be.model.cache.ComponentCache componentCache) {
+        this.toscaOperationFacade = toscaOperationFacade;
+        ComponentCache = componentCache;
+    }
 
-	public ToscaOperationFacade getToscaOperationFacade() {
-		return toscaOperationFacade;
-	}
+    public ToscaOperationFacade getToscaOperationFacade() {
+        return toscaOperationFacade;
+    }
 
-	public org.openecomp.sdc.be.model.cache.ComponentCache getComponentCache() {
-		return ComponentCache;
-	}
+    public org.openecomp.sdc.be.model.cache.ComponentCache getComponentCache() {
+        return ComponentCache;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java
index ff1c21c..daf14b0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java
@@ -20,8 +20,7 @@
 
 package org.openecomp.sdc.be.model.cache.jobs;
 
-import java.util.function.Function;
-
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
@@ -29,103 +28,102 @@
 import org.openecomp.sdc.be.model.cache.DaoInfo;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
-import fj.data.Either;
+import java.util.function.Function;
 
 /**
  * Created by mlando on 9/7/2016.
  */
 public class CheckAndUpdateJob extends Job {
-	private static Logger log = LoggerFactory.getLogger(CheckAndUpdateJob.class.getName());
+    private static final Logger log = Logger.getLogger(CheckAndUpdateJob.class.getName());
 
-	public CheckAndUpdateJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) {
-		super(daoInfo, componentId, nodeTypeEnum, timestamp);
-	}
+    public CheckAndUpdateJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) {
+        super(daoInfo, componentId, nodeTypeEnum, timestamp);
+    }
 
-	@Override
-	public Object doWork() {
-		log.trace("starting work on job.");
-		log.trace("update cache for componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, nodeTypeEnum,
-				timestamp);
+    @Override
+    public Object doWork() {
+        log.trace("starting work on job.");
+        log.trace("update cache for componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, nodeTypeEnum,
+                timestamp);
 
-		try {
+        try {
 
-			// get from cache
-			Either<ImmutablePair<Component, Long>, ActionStatus> cacheResult = daoInfo.getComponentCache()
-					.getComponentAndTime(componentId, Function.identity());
-			// if error while getting from cache abort and update
-			if (cacheResult.isRight()) {
-				// genral error
-				if (!ActionStatus.RESOURCE_NOT_FOUND.equals(cacheResult.right().value())
-						&& !ActionStatus.INVALID_CONTENT.equals(cacheResult.right().value())) {
-					log.debug("failed to get component:{} from cache error:{}", componentId,
-							cacheResult.right().value());
-					return false;
-				}
-				// component not in cache put there
-				else {
-					return updateCache(componentId, nodeTypeEnum, timestamp);
-				}
-			}
-			ImmutablePair<Component, Long> recored = cacheResult.left().value();
-			// the cache has allready been updated exit
-			if (this.timestamp < recored.getRight()) {
-				log.debug("job timestemp:{} is smaller then the cache timestamp:{} no update is needed.",
-						this.timestamp, recored.getRight());
-				return false;
-			}
-			return updateCache(componentId, nodeTypeEnum, timestamp);
+            // get from cache
+            Either<ImmutablePair<Component, Long>, ActionStatus> cacheResult = daoInfo.getComponentCache()
+                    .getComponentAndTime(componentId, Function.identity());
+            // if error while getting from cache abort and update
+            if (cacheResult.isRight()) {
+                // genral error
+                if (!ActionStatus.RESOURCE_NOT_FOUND.equals(cacheResult.right().value())
+                        && !ActionStatus.INVALID_CONTENT.equals(cacheResult.right().value())) {
+                    log.debug("failed to get component:{} from cache error:{}", componentId,
+                            cacheResult.right().value());
+                    return false;
+                }
+                // component not in cache put there
+                else {
+                    return updateCache(componentId, nodeTypeEnum, timestamp);
+                }
+            }
+            ImmutablePair<Component, Long> recored = cacheResult.left().value();
+            // the cache has allready been updated exit
+            if (this.timestamp < recored.getRight()) {
+                log.debug("job timestemp:{} is smaller then the cache timestamp:{} no update is needed.",
+                        this.timestamp, recored.getRight());
+                return false;
+            }
+            return updateCache(componentId, nodeTypeEnum, timestamp);
 
-		} catch (Exception e) {
-			log.debug("an exception was encountered during CheckAndUpdateJob", e);
-		} finally {
-			daoInfo.getToscaOperationFacade().commit();
-		}
-		return false;
-	}
+        } catch (Exception e) {
+            log.debug("an exception was encountered during CheckAndUpdateJob", e);
+        } finally {
+            daoInfo.getToscaOperationFacade().commit();
+        }
+        return false;
+    }
 
-	/**
-	 * @param componentId
-	 * @param nodeTypeEnum
-	 * @return
-	 */
-	private boolean updateCache(String componentId, NodeTypeEnum nodeTypeEnum, Long timestamp) {
-		// get component from cache
-		Either<ComponentMetadataData, StorageOperationStatus> metaDataRes = getComponentMetaData(componentId,
-				nodeTypeEnum);
-		if (metaDataRes.isRight()) {
-			return false;
-		}
-		ComponentMetadataData metaData = metaDataRes.left().value();
-		// the job time is older then the one on graph nothing to do there is a
-		// job that will handle this.
-		Long graphTimestamp = metaData.getMetadataDataDefinition().getLastUpdateDate();
-		if (timestamp < graphTimestamp) {
-			log.debug(
-					"the job timestamp:{} is smaller then the graph timestamp:{}. exiting because another job will update the cache.",
-					timestamp, graphTimestamp);
-			return false;
-		} else {
-			// update cache
-			// get component from grath
-			Either<Component, StorageOperationStatus> componentRes = daoInfo.getToscaOperationFacade().getToscaElement(componentId);
-			if (componentRes.isRight()) {
-				log.debug("failed to get full component:{} from graph status:{}", componentId,
-						componentRes.right().value());
-				return false;
-			}
-			Component component = componentRes.left().value();
-			// store in cache
-			if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) {
-				log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum);
-				return false;
-			}
-		}
-		log.debug("cache successfully updated for componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId,
-				nodeTypeEnum, timestamp);
-		return true;
-	}
+    /**
+     * @param componentId
+     * @param nodeTypeEnum
+     * @return
+     */
+    private boolean updateCache(String componentId, NodeTypeEnum nodeTypeEnum, Long timestamp) {
+        // get component from cache
+        Either<ComponentMetadataData, StorageOperationStatus> metaDataRes = getComponentMetaData(componentId,
+                nodeTypeEnum);
+        if (metaDataRes.isRight()) {
+            return false;
+        }
+        ComponentMetadataData metaData = metaDataRes.left().value();
+        // the job time is older then the one on graph nothing to do there is a
+        // job that will handle this.
+        Long graphTimestamp = metaData.getMetadataDataDefinition().getLastUpdateDate();
+        if (timestamp < graphTimestamp) {
+            log.debug(
+                    "the job timestamp:{} is smaller then the graph timestamp:{}. exiting because another job will update the cache.",
+                    timestamp, graphTimestamp);
+            return false;
+        } else {
+            // update cache
+            // get component from grath
+            Either<Component, StorageOperationStatus> componentRes = daoInfo.getToscaOperationFacade().getToscaElement(componentId);
+            if (componentRes.isRight()) {
+                log.debug("failed to get full component:{} from graph status:{}", componentId,
+                        componentRes.right().value());
+                return false;
+            }
+            Component component = componentRes.left().value();
+            // store in cache
+            if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) {
+                log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum);
+                return false;
+            }
+        }
+        log.debug("cache successfully updated for componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId,
+                nodeTypeEnum, timestamp);
+        return true;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.java
index 20dd414..0d883a7 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.java
@@ -23,38 +23,37 @@
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.cache.DaoInfo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
 /**
  * Created by mlando on 9/20/2016.
  */
 public class DeleteJob extends Job {
-	private static Logger log = LoggerFactory.getLogger(DeleteJob.class.getName());
+    private static final Logger log = Logger.getLogger(DeleteJob.class.getName());
 
-	public DeleteJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) {
-		super(daoInfo, componentId, nodeTypeEnum, timestamp);
+    public DeleteJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) {
+        super(daoInfo, componentId, nodeTypeEnum, timestamp);
 
-	}
+    }
 
-	@Override
-	public Object doWork() {
-		try {
-			log.trace("starting work on job.");
-			log.trace("delete component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId,
-					nodeTypeEnum, timestamp);
-			ActionStatus status = this.daoInfo.getComponentCache().deleteComponentFromCache(componentId);
-			if (!ActionStatus.OK.equals(status)) {
-				log.debug("failed to delete componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum);
-				return false;
-			}
-			log.trace("cache successfully deleted  componentId:{} nodeTypeEnum:{} timestamp:{}.", componentId,
-					nodeTypeEnum, timestamp);
-			return true;
-		} catch (Exception e) {
-			log.debug("an exception was encountered durring deletejob", e);
-		}
-		return false;
+    @Override
+    public Object doWork() {
+        try {
+            log.trace("starting work on job.");
+            log.trace("delete component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId,
+                    nodeTypeEnum, timestamp);
+            ActionStatus status = this.daoInfo.getComponentCache().deleteComponentFromCache(componentId);
+            if (!ActionStatus.OK.equals(status)) {
+                log.debug("failed to delete componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum);
+                return false;
+            }
+            log.trace("cache successfully deleted  componentId:{} nodeTypeEnum:{} timestamp:{}.", componentId,
+                    nodeTypeEnum, timestamp);
+            return true;
+        } catch (Exception e) {
+            log.debug("an exception was encountered durring deletejob", e);
+        }
+        return false;
 
-	}
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.java
index f701aaf..593df2b 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.java
@@ -20,70 +20,68 @@
 
 package org.openecomp.sdc.be.model.cache.jobs;
 
+import fj.data.Either;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.cache.DaoInfo;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fj.data.Either;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
 public abstract class Job<E> {
-	private static Logger log = LoggerFactory.getLogger(Job.class.getName());
-	protected DaoInfo daoInfo;
-	protected String componentId;
-	protected long timestamp;
-	protected NodeTypeEnum nodeTypeEnum;
+    private static final Logger log = Logger.getLogger(Job.class.getName());
+    protected DaoInfo daoInfo;
+    protected String componentId;
+    protected long timestamp;
+    protected NodeTypeEnum nodeTypeEnum;
 
-	protected Job(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) {
-		this.daoInfo = daoInfo;
-		this.componentId = componentId;
-		this.timestamp = timestamp;
-		this.nodeTypeEnum = nodeTypeEnum;
-	}
+    protected Job(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) {
+        this.daoInfo = daoInfo;
+        this.componentId = componentId;
+        this.timestamp = timestamp;
+        this.nodeTypeEnum = nodeTypeEnum;
+    }
 
-	protected Job(DaoInfo daoInfo, Component component, NodeTypeEnum nodeTypeEnum) {
-		this.daoInfo = daoInfo;
-		this.componentId = component.getUniqueId();
-		this.timestamp = component.getLastUpdateDate();
-		this.nodeTypeEnum = nodeTypeEnum;
-	}
+    protected Job(DaoInfo daoInfo, Component component, NodeTypeEnum nodeTypeEnum) {
+        this.daoInfo = daoInfo;
+        this.componentId = component.getUniqueId();
+        this.timestamp = component.getLastUpdateDate();
+        this.nodeTypeEnum = nodeTypeEnum;
+    }
 
-	public abstract E doWork();
+    public abstract E doWork();
 
-	protected Either<ComponentMetadataData, StorageOperationStatus> getComponentMetaData(String componentId,
-			NodeTypeEnum nodeTypeEnum) {
-		Either<ComponentMetadataData, StorageOperationStatus> metaDataRes = daoInfo.getToscaOperationFacade().getComponentMetadata(componentId);
-		if (metaDataRes.isRight()) {
-			// in case we cant find the component on graph exit
-			if (StorageOperationStatus.NOT_FOUND.equals(metaDataRes.right().value())) {
-				log.debug("failed to locate component:{} on graph status:{}", componentId, metaDataRes.right().value());
-			} else {
-				log.debug("failed to get component:{} from graph status:{}", componentId, metaDataRes.right().value());
-			}
-		}
-		return metaDataRes;
-	}
+    protected Either<ComponentMetadataData, StorageOperationStatus> getComponentMetaData(String componentId,
+            NodeTypeEnum nodeTypeEnum) {
+        Either<ComponentMetadataData, StorageOperationStatus> metaDataRes = daoInfo.getToscaOperationFacade().getComponentMetadata(componentId);
+        if (metaDataRes.isRight()) {
+            // in case we cant find the component on graph exit
+            if (StorageOperationStatus.NOT_FOUND.equals(metaDataRes.right().value())) {
+                log.debug("failed to locate component:{} on graph status:{}", componentId, metaDataRes.right().value());
+            } else {
+                log.debug("failed to get component:{} from graph status:{}", componentId, metaDataRes.right().value());
+            }
+        }
+        return metaDataRes;
+    }
 
-	protected NodeTypeEnum getNodeTypeFromComponentType(ComponentTypeEnum type) {
-		NodeTypeEnum result = null;
-		switch (type) {
-		case PRODUCT:
-			result = NodeTypeEnum.Product;
-			break;
-		case RESOURCE:
-			result = NodeTypeEnum.Resource;
-			break;
-		case SERVICE:
-			result = NodeTypeEnum.Service;
-			break;
-		default:
+    protected NodeTypeEnum getNodeTypeFromComponentType(ComponentTypeEnum type) {
+        NodeTypeEnum result = null;
+        switch (type) {
+        case PRODUCT:
+            result = NodeTypeEnum.Product;
+            break;
+        case RESOURCE:
+            result = NodeTypeEnum.Resource;
+            break;
+        case SERVICE:
+            result = NodeTypeEnum.Service;
+            break;
+        default:
 
-		}
-		return result;
+        }
+        return result;
 
-	}
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.java
index 641d125..cb33a02 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.java
@@ -20,54 +20,52 @@
 
 package org.openecomp.sdc.be.model.cache.jobs;
 
+import fj.data.Either;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.cache.DaoInfo;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fj.data.Either;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
 /**
  * Created by mlando on 9/20/2016.
  */
 public class OverrideJob extends Job {
-	private static Logger log = LoggerFactory.getLogger(OverrideJob.class.getName());
+    private static final Logger log = Logger.getLogger(OverrideJob.class.getName());
 
-	public OverrideJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) {
-		super(daoInfo, componentId, nodeTypeEnum, timestamp);
+    public OverrideJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) {
+        super(daoInfo, componentId, nodeTypeEnum, timestamp);
 
-	}
+    }
 
-	@Override
-	public Object doWork() {
-		try {
-			log.trace("starting work on job.");
-			log.trace("override component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId,
-					nodeTypeEnum, timestamp);
-			// get component from grath
-			Either<Component, StorageOperationStatus> componentRes = daoInfo.getToscaOperationFacade().getToscaElement(componentId);
-			if (componentRes.isRight()) {
-				log.debug("failed to get full component:{} from graph status:{}", componentId,
-						componentRes.right().value());
-				return false;
-			}
-			Component component = componentRes.left().value();
-			// store in cache
-			if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) {
-				log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum);
-				return false;
-			}
-			log.debug("cache successfully overrided  componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId,
-					nodeTypeEnum, timestamp);
-			return true;
-		} catch (Exception e) {
-			log.debug("an exception was encountered during OverrideJob", e);
-		} finally {
-			this.daoInfo.getToscaOperationFacade().commit();
-		}
-		return false;
+    @Override
+    public Object doWork() {
+        try {
+            log.trace("starting work on job.");
+            log.trace("override component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId,
+                    nodeTypeEnum, timestamp);
+            // get component from grath
+            Either<Component, StorageOperationStatus> componentRes = daoInfo.getToscaOperationFacade().getToscaElement(componentId);
+            if (componentRes.isRight()) {
+                log.debug("failed to get full component:{} from graph status:{}", componentId,
+                        componentRes.right().value());
+                return false;
+            }
+            Component component = componentRes.left().value();
+            // store in cache
+            if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) {
+                log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum);
+                return false;
+            }
+            log.debug("cache successfully overrided  componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId,
+                    nodeTypeEnum, timestamp);
+            return true;
+        } catch (Exception e) {
+            log.debug("an exception was encountered during OverrideJob", e);
+        } finally {
+            this.daoInfo.getToscaOperationFacade().commit();
+        }
+        return false;
 
-	}
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.java
index c282e5d..c8baafe 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.java
@@ -23,37 +23,36 @@
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.cache.DaoInfo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
 /**
  * Created by mlando on 9/11/2016.
  */
 public class StoreJob extends Job {
-	private static Logger log = LoggerFactory.getLogger(StoreJob.class.getName());
-	private Component component;
+    private static final Logger log = Logger.getLogger(StoreJob.class.getName());
+    private Component component;
 
-	public StoreJob(DaoInfo daoInfo, Component component, NodeTypeEnum nodeTypeEnum) {
-		super(daoInfo, component, nodeTypeEnum);
-		this.component = component;
-	}
+    public StoreJob(DaoInfo daoInfo, Component component, NodeTypeEnum nodeTypeEnum) {
+        super(daoInfo, component, nodeTypeEnum);
+        this.component = component;
+    }
 
-	@Override
-	public Object doWork() {
-		try {
-			log.trace("starting work on job.");
-			log.trace("store component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, nodeTypeEnum, timestamp);
-			if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) {
-				log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum);
-				return false;
-			}
-			log.debug("cache successfully updated for componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId, nodeTypeEnum, timestamp);
-			return true;
+    @Override
+    public Object doWork() {
+        try {
+            log.trace("starting work on job.");
+            log.trace("store component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, nodeTypeEnum, timestamp);
+            if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) {
+                log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum);
+                return false;
+            }
+            log.debug("cache successfully updated for componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId, nodeTypeEnum, timestamp);
+            return true;
 
-		} catch (Exception e) {
-			log.debug("an exception was encountered during StoreJob", e);
-		}
-		return false;
-	}
+        } catch (Exception e) {
+            log.debug("an exception was encountered during StoreJob", e);
+        }
+        return false;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.java
index d29ade9..e70916f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.java
@@ -20,13 +20,12 @@
 
 package org.openecomp.sdc.be.model.cache.workers;
 
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
 import org.openecomp.sdc.be.model.cache.jobs.Job;
 import org.openecomp.sdc.be.workers.Worker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Created by mlando on 9/6/2016. the class represents a worker the pull job
@@ -34,59 +33,59 @@
  *
  */
 public class CacheWorker implements Runnable, IWorker {
-	private String workerName;
-	private static Logger log = LoggerFactory.getLogger(Worker.class.getName());
-	private LinkedBlockingQueue<Job> jobQueue;
-	private volatile boolean shutdown = false;
+    private String workerName;
+    private static final Logger log = Logger.getLogger(Worker.class.getName());
+    private LinkedBlockingQueue<Job> jobQueue;
+    private volatile boolean shutdown = false;
 
-	/**
-	 * constructor
-	 * 
-	 * @param workerName
-	 *            the name of the given worker
-	 * @param jobQueue
-	 *            the queue the worker will block on.
-	 */
-	public CacheWorker(String workerName, LinkedBlockingQueue<Job> jobQueue) {
-		this.workerName = workerName;
-		this.jobQueue = jobQueue;
-	}
+    /**
+     * constructor
+     *
+     * @param workerName
+     *            the name of the given worker
+     * @param jobQueue
+     *            the queue the worker will block on.
+     */
+    public CacheWorker(String workerName, LinkedBlockingQueue<Job> jobQueue) {
+        this.workerName = workerName;
+        this.jobQueue = jobQueue;
+    }
 
-	/**
-	 * the method will try to get a job if one is avilable it will be retrived
-	 * and handled. if no jobs are available the worker will block for 500
-	 * milliseconds and then it wil check if it needs to shutdown. if not it
-	 * will block again and so on until sutdown or a new job is available
-	 */
-	@Override
-	public void run() {
-		while (true) {
-			log.trace("CacheWorker:{} doing work", workerName);
-			try {
-				Job job = jobQueue.poll(500, TimeUnit.MILLISECONDS);
-				if (job != null) {
-					job.doWork();
-					log.trace("worker:{} done with work", workerName);
-				}
-			} catch (Throwable e) {
-				log.debug("worker {} failed during job execution.", workerName);
-				log.debug("exception", e);
-			}
-			if (shutdown) {
-				log.debug("worker:{} nothing to do stoping", workerName);
-				break;
-			}
-		}
+    /**
+     * the method will try to get a job if one is avilable it will be retrived
+     * and handled. if no jobs are available the worker will block for 500
+     * milliseconds and then it wil check if it needs to shutdown. if not it
+     * will block again and so on until sutdown or a new job is available
+     */
+    @Override
+    public void run() {
+        while (true) {
+            log.trace("CacheWorker:{} doing work", workerName);
+            try {
+                Job job = jobQueue.poll(500, TimeUnit.MILLISECONDS);
+                if (job != null) {
+                    job.doWork();
+                    log.trace("worker:{} done with work", workerName);
+                }
+            } catch (Exception e) {
+                log.debug("worker {} failed during job execution.", workerName);
+                log.debug("exception", e);
+            }
+            if (shutdown) {
+                log.debug("worker:{} nothing to do stoping", workerName);
+                break;
+            }
+        }
 
-	}
+    }
 
-	/**
-	 * the method sets the shutdown flag, when set the worker will stop it's
-	 * execution as soon as possible with out completing its work
-	 */
-	@Override
-	public void shutDown() {
-		this.shutdown = true;
-	}
+    /**
+     * the method sets the shutdown flag, when set the worker will stop it's
+     * execution as soon as possible with out completing its work
+     */
+    @Override
+    public void shutDown() {
+        this.shutdown = true;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java
index fcdf9f4..fa508a4 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java
@@ -24,5 +24,5 @@
  * Created by mlando on 9/6/2016.
  */
 public interface IWorker {
-	void shutDown();
+    void shutDown();
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java
index 64cc1c8..169f857 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java
@@ -20,12 +20,7 @@
 
 package org.openecomp.sdc.be.model.cache.workers;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
@@ -34,10 +29,13 @@
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.be.resources.data.ComponentCacheData;
 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
-import fj.data.Either;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * the class creates a worker that is used to update cache date, in case of
@@ -45,225 +43,225 @@
  */
 public class SyncWorker implements Runnable, IWorker {
 
-	private static Logger log = LoggerFactory.getLogger(SyncWorker.class.getName());
-	private final CacheMangerOperation cacheMangerOperation;
-	private final String workerName;
-	private volatile boolean shutdown = false;
-	private Map<String, ComponentCacheData> cacheIdAndTimeMap;
-	private long updateDelayInMilliseconds = 60 * 60 * 1000;
+    private static final Logger log = Logger.getLogger(SyncWorker.class.getName());
+    private final CacheMangerOperation cacheMangerOperation;
+    private final String workerName;
+    private volatile boolean shutdown = false;
+    private Map<String, ComponentCacheData> cacheIdAndTimeMap;
+    private long updateDelayInMilliseconds = 60 * 60 * 1000L;
 
-	/**
-	 * creates the sync worker
-	 * 
-	 * @param workerName
-	 *            the name of the worker
-	 * @param cacheMangerOperation
-	 *            responsible for all persistence's operations to graph and the
-	 *            cache
-	 */
-	public SyncWorker(String workerName, CacheMangerOperation cacheMangerOperation) {
-		this.workerName = workerName;
-		this.cacheMangerOperation = cacheMangerOperation;
-	}
+    /**
+     * creates the sync worker
+     *
+     * @param workerName
+     *            the name of the worker
+     * @param cacheMangerOperation
+     *            responsible for all persistence's operations to graph and the
+     *            cache
+     */
+    public SyncWorker(String workerName, CacheMangerOperation cacheMangerOperation) {
+        this.workerName = workerName;
+        this.cacheMangerOperation = cacheMangerOperation;
+    }
 
-	/**
-	 * the method collects all the resources/services/products from graph and
-	 * checks if the component representing them in the cache is valid logic: if
-	 * the record is present in the graph but not in cache -> create a job that
-	 * will update the record oin cache if the timestamp of the record in cache
-	 * is older than the timestamp on the graph -> create a job that will update
-	 * the record oin cache otherwise no update is required
-	 */
-	@Override
-	public void run() {
-		try {
-			collectAllCacheRecords();
-			syncCacheByComponentType(NodeTypeEnum.Resource);
-			syncCacheByComponentType(NodeTypeEnum.Service);
-			syncCacheByComponentType(NodeTypeEnum.Product);
-			clearCacheRecords();
+    /**
+     * the method collects all the resources/services/products from graph and
+     * checks if the component representing them in the cache is valid logic: if
+     * the record is present in the graph but not in cache -> create a job that
+     * will update the record oin cache if the timestamp of the record in cache
+     * is older than the timestamp on the graph -> create a job that will update
+     * the record oin cache otherwise no update is required
+     */
+    @Override
+    public void run() {
+        try {
+            collectAllCacheRecords();
+            syncCacheByComponentType(NodeTypeEnum.Resource);
+            syncCacheByComponentType(NodeTypeEnum.Service);
+            syncCacheByComponentType(NodeTypeEnum.Product);
+            clearCacheRecords();
 
-		} catch (Exception e) {
-			log.debug("sync worker:{} encounered an exception", workerName);
-			log.debug("exception", e);
-		} finally {
-			this.cacheMangerOperation.getTitanGenericDao().commit();
-		}
-	}
+        } catch (Exception e) {
+            log.debug("sync worker:{} encounered an exception", workerName);
+            log.debug("exception", e);
+        } finally {
+            this.cacheMangerOperation.getTitanGenericDao().commit();
+        }
+    }
 
-	/**
-	 * the method checks for each component in the cache except the ones that
-	 * were update during the sync, if they exist on the graph if not a job to
-	 * remove them is created
-	 */
-	private void clearCacheRecords() {
-		cacheIdAndTimeMap.forEach((k, v) -> {
-			try {
-				Either<ComponentMetadataData, TitanOperationStatus> componentFromGraphRes = getComponentMetaData(k,
-						NodeTypeEnum.getByName(v.getType()));
-				if (componentFromGraphRes.isRight()) {
-					TitanOperationStatus error = componentFromGraphRes.right().value();
-					if (TitanOperationStatus.NOT_FOUND.equals(error)) {
-						long delay = System.currentTimeMillis() - v.getModificationTime().getTime();
-						if (delay > updateDelayInMilliseconds) {
-							this.cacheMangerOperation.deleteComponentInCache(k, v.getModificationTime().getTime(),
-									NodeTypeEnum.getByName(v.getType()));
-						} else {
-							log.trace(
-									"no delete done because an hour did not pass since the delete was done  timeSinceUpdate {} < updateDelayInMilliseconds {} ",
-									delay, updateDelayInMilliseconds);
-						}
-					} else {
-						log.debug("failed to get metadata for id:{} from graph error:{}", k, error);
-					}
-				} else {
-					log.trace("id {} is in graph nothing to do");
-				}
-			} catch (Exception e) {
-				log.debug("during clean cache records an exception was thrown", e);
-			}
-		});
-	}
+    /**
+     * the method checks for each component in the cache except the ones that
+     * were update during the sync, if they exist on the graph if not a job to
+     * remove them is created
+     */
+    private void clearCacheRecords() {
+        cacheIdAndTimeMap.forEach((k, v) -> {
+            try {
+                Either<ComponentMetadataData, TitanOperationStatus> componentFromGraphRes = getComponentMetaData(k,
+                        NodeTypeEnum.getByName(v.getType()));
+                if (componentFromGraphRes.isRight()) {
+                    TitanOperationStatus error = componentFromGraphRes.right().value();
+                    if (TitanOperationStatus.NOT_FOUND.equals(error)) {
+                        long delay = System.currentTimeMillis() - v.getModificationTime().getTime();
+                        if (delay > updateDelayInMilliseconds) {
+                            this.cacheMangerOperation.deleteComponentInCache(k, v.getModificationTime().getTime(),
+                                    NodeTypeEnum.getByName(v.getType()));
+                        } else {
+                            log.trace(
+                                    "no delete done because an hour did not pass since the delete was done  timeSinceUpdate {} < updateDelayInMilliseconds {} ",
+                                    delay, updateDelayInMilliseconds);
+                        }
+                    } else {
+                        log.debug("failed to get metadata for id:{} from graph error:{}", k, error);
+                    }
+                } else {
+                    log.trace("id {} is in graph nothing to do", k);
+                }
+            } catch (Exception e) {
+                log.debug("during clean cache records an exception was thrown", e);
+            }
+        });
+    }
 
-	/**
-	 * the method collects all the records from cache except the component
-	 * itself
-	 */
-	public void collectAllCacheRecords() {
-		Either<List<ComponentCacheData>, ActionStatus> getAllRes = this.cacheMangerOperation.getComponentCache()
-				.getAllComponentIdTimeAndType();
-		if (getAllRes.isRight()) {
-			log.debug("error while trying to get all records from cache error:{}", getAllRes.right().value());
-			cacheIdAndTimeMap = new HashMap<>();
-		} else {
-			cacheIdAndTimeMap = getAllRes.left().value().stream().collect(Collectors.toMap(e -> e.getId(), e -> e));
-		}
-	}
+    /**
+     * the method collects all the records from cache except the component
+     * itself
+     */
+    public void collectAllCacheRecords() {
+        Either<List<ComponentCacheData>, ActionStatus> getAllRes = this.cacheMangerOperation.getComponentCache()
+                .getAllComponentIdTimeAndType();
+        if (getAllRes.isRight()) {
+            log.debug("error while trying to get all records from cache error:{}", getAllRes.right().value());
+            cacheIdAndTimeMap = new HashMap<>();
+        } else {
+            cacheIdAndTimeMap = getAllRes.left().value().stream().collect(Collectors.toMap(ComponentCacheData::getId, e -> e));
+        }
+    }
 
-	/**
-	 * the method checks that the records ot the given type are sync between the
-	 * cache and the graph
-	 * 
-	 * @param nodeTypeEnum
-	 *            the type of components we want to sync
-	 */
-	private void syncCacheByComponentType(NodeTypeEnum nodeTypeEnum) {
-		if (!this.shutdown) {
-			log.trace("syncCache records of type:{} .", nodeTypeEnum);
-			Either<List<ComponentMetadataData>, TitanOperationStatus> getAllResult = getAllComponentsMetaData(
-					nodeTypeEnum);
-			List<ComponentMetadataData> componentList = new ArrayList<>();
-			if (getAllResult.isRight() && !TitanOperationStatus.NOT_FOUND.equals(getAllResult.right().value())) {
-				log.debug("error while trying to get all components of type:{} TitanOperationStatus:{}.", nodeTypeEnum,
-						getAllResult.right().value());
-				return;
-			}
-			if (getAllResult.isLeft()) {
-				componentList = getAllResult.left().value();
-				log.trace("get all components of type:{} returned:{} components.", nodeTypeEnum, componentList.size());
-			}
-			componentList.forEach(this::checkAndUpdateCacheComponent);
-			log.trace("syncCache records of type:{} was successful.", nodeTypeEnum);
-		}
-	}
+    /**
+     * the method checks that the records ot the given type are sync between the
+     * cache and the graph
+     *
+     * @param nodeTypeEnum
+     *            the type of components we want to sync
+     */
+    private void syncCacheByComponentType(NodeTypeEnum nodeTypeEnum) {
+        if (!this.shutdown) {
+            log.trace("syncCache records of type:{} .", nodeTypeEnum);
+            Either<List<ComponentMetadataData>, TitanOperationStatus> getAllResult = getAllComponentsMetaData(
+                    nodeTypeEnum);
+            List<ComponentMetadataData> componentList = new ArrayList<>();
+            if (getAllResult.isRight() && !TitanOperationStatus.NOT_FOUND.equals(getAllResult.right().value())) {
+                log.debug("error while trying to get all components of type:{} TitanOperationStatus:{}.", nodeTypeEnum,
+                        getAllResult.right().value());
+                return;
+            }
+            if (getAllResult.isLeft()) {
+                componentList = getAllResult.left().value();
+                log.trace("get all components of type:{} returned:{} components.", nodeTypeEnum, componentList.size());
+            }
+            componentList.forEach(this::checkAndUpdateCacheComponent);
+            log.trace("syncCache records of type:{} was successful.", nodeTypeEnum);
+        }
+    }
 
-	/**
-	 * the method compares the given component to the record in the cache if the
-	 * record is not in the cache a job to update the cache for this record will
-	 * be created. if the record is present in the graph but not in cache ->
-	 * create a job that will update the record oin cache if the timestamp of
-	 * the record in cache is older than the timestamp on the graph -> create a
-	 * job that will update the record oin cache if the retried component from
-	 * cache fails to be deserialized -> create job to override it otherwise no
-	 * update is required
-	 * 
-	 * @param metadataData
-	 *            the date of the node we want to compare to the value in the
-	 *            cache
-	 */
-	private void checkAndUpdateCacheComponent(ComponentMetadataData metadataData) {
-		long timeSinceUpdate = System.currentTimeMillis()
-				- metadataData.getMetadataDataDefinition().getLastUpdateDate();
-		if (timeSinceUpdate >= updateDelayInMilliseconds) {
-			String uid = metadataData.getMetadataDataDefinition().getUniqueId();
-			log.trace("checking cache if record for uid:{} needs to be updated.", uid);
-			Either<Component, ActionStatus> cacheResult = this.cacheMangerOperation.getComponentCache()
-					.getComponent(uid);
-			if (cacheResult.isRight()) {
-				ActionStatus actionStatus = cacheResult.right().value();
-				if (ActionStatus.RESOURCE_NOT_FOUND.equals(actionStatus)) {
-					log.trace("record for uid:{} not found in cache. creating an update job.", uid);
-					this.cacheMangerOperation.updateComponentInCache(uid,
-							metadataData.getMetadataDataDefinition().getLastUpdateDate(),
-							NodeTypeEnum.getByName(metadataData.getLabel()));
-				} else if (ActionStatus.CONVERT_COMPONENT_ERROR.equals(actionStatus)) {
-					log.trace("uid:{} found in cache but we failed deserializing it. creating an override job  .", uid);
-					this.cacheMangerOperation.overideComponentInCache(uid,
-							metadataData.getMetadataDataDefinition().getLastUpdateDate(),
-							NodeTypeEnum.getByName(metadataData.getLabel()));
-				} else {
-					log.debug("during lookup for uid:{} an error accords status:{} .", uid, actionStatus);
-				}
-			} else {
-				log.trace("uid:{} found in cache.", uid);
-				this.cacheIdAndTimeMap.remove(uid);
-				Component cacheComponent = cacheResult.left().value();
-				Long cacheTimestamp = cacheComponent.getLastUpdateDate();
-				Long graphTimestamp = metadataData.getMetadataDataDefinition().getLastUpdateDate();
-				if (cacheTimestamp < graphTimestamp) {
-					log.trace("uid:{} found in cache. cache Timestamp {} < graph timestamp , creating an update job  .",
-							uid, cacheTimestamp, graphTimestamp);
-					this.cacheMangerOperation.updateComponentInCache(uid, graphTimestamp,
-							NodeTypeEnum.getByName(metadataData.getLabel()));
-				} else {
-					log.trace("uid:{} found in cache. cache Timestamp {} => graph timestamp , no update is needed .",
-							uid, cacheTimestamp, graphTimestamp);
-				}
-			}
-		} else {
-			log.trace(
-					"no update done because an hour did not pass since the update was done  timeSinceUpdate {} < updateDelayInMilliseconds {} ",
-					timeSinceUpdate, updateDelayInMilliseconds);
-		}
-	}
+    /**
+     * the method compares the given component to the record in the cache if the
+     * record is not in the cache a job to update the cache for this record will
+     * be created. if the record is present in the graph but not in cache ->
+     * create a job that will update the record oin cache if the timestamp of
+     * the record in cache is older than the timestamp on the graph -> create a
+     * job that will update the record oin cache if the retried component from
+     * cache fails to be deserialized -> create job to override it otherwise no
+     * update is required
+     *
+     * @param metadataData
+     *            the date of the node we want to compare to the value in the
+     *            cache
+     */
+    private void checkAndUpdateCacheComponent(ComponentMetadataData metadataData) {
+        long timeSinceUpdate = System.currentTimeMillis()
+                - metadataData.getMetadataDataDefinition().getLastUpdateDate();
+        if (timeSinceUpdate >= updateDelayInMilliseconds) {
+            String uid = metadataData.getMetadataDataDefinition().getUniqueId();
+            log.trace("checking cache if record for uid:{} needs to be updated.", uid);
+            Either<Component, ActionStatus> cacheResult = this.cacheMangerOperation.getComponentCache()
+                    .getComponent(uid);
+            if (cacheResult.isRight()) {
+                ActionStatus actionStatus = cacheResult.right().value();
+                if (ActionStatus.RESOURCE_NOT_FOUND.equals(actionStatus)) {
+                    log.trace("record for uid:{} not found in cache. creating an update job.", uid);
+                    this.cacheMangerOperation.updateComponentInCache(uid,
+                            metadataData.getMetadataDataDefinition().getLastUpdateDate(),
+                            NodeTypeEnum.getByName(metadataData.getLabel()));
+                } else if (ActionStatus.CONVERT_COMPONENT_ERROR.equals(actionStatus)) {
+                    log.trace("uid:{} found in cache but we failed deserializing it. creating an override job  .", uid);
+                    this.cacheMangerOperation.overideComponentInCache(uid,
+                            metadataData.getMetadataDataDefinition().getLastUpdateDate(),
+                            NodeTypeEnum.getByName(metadataData.getLabel()));
+                } else {
+                    log.debug("during lookup for uid:{} an error accords status:{} .", uid, actionStatus);
+                }
+            } else {
+                log.trace("uid:{} found in cache.", uid);
+                this.cacheIdAndTimeMap.remove(uid);
+                Component cacheComponent = cacheResult.left().value();
+                Long cacheTimestamp = cacheComponent.getLastUpdateDate();
+                Long graphTimestamp = metadataData.getMetadataDataDefinition().getLastUpdateDate();
+                if (cacheTimestamp < graphTimestamp) {
+                    log.trace("uid:{} found in cache. cache Timestamp {} < graph timestamp {} , creating an update job  .",
+                            uid, cacheTimestamp, graphTimestamp);
+                    this.cacheMangerOperation.updateComponentInCache(uid, graphTimestamp,
+                            NodeTypeEnum.getByName(metadataData.getLabel()));
+                } else {
+                    log.trace("uid:{} found in cache. cache Timestamp {} => graph timestamp {}, no update is needed .",
+                            uid, cacheTimestamp, graphTimestamp);
+                }
+            }
+        } else {
+            log.trace(
+                    "no update done because an hour did not pass since the update was done  timeSinceUpdate {} < updateDelayInMilliseconds {} ",
+                    timeSinceUpdate, updateDelayInMilliseconds);
+        }
+    }
 
-	/**
-	 * the method sets the shutdown flag, when set the worker will stop it's
-	 * execution as soon as possible with out completing its work
-	 */
-	@Override
-	public void shutDown() {
-		log.debug("syncWorker {} shuting down.", workerName);
-		this.shutdown = true;
-	}
+    /**
+     * the method sets the shutdown flag, when set the worker will stop it's
+     * execution as soon as possible with out completing its work
+     */
+    @Override
+    public void shutDown() {
+        log.debug("syncWorker {} shuting down.", workerName);
+        this.shutdown = true;
+    }
 
-	/**
-	 * the method retrives all nodes matching the given node type from the graph
-	 * 
-	 * @param nodeTypeEnum
-	 *            node type we want to lookup on the graph
-	 * @return a list of retrieved nodes matching the given type or not found in
-	 *         case no nodes were found or error in case of failure
-	 */
-	private Either<List<ComponentMetadataData>, TitanOperationStatus> getAllComponentsMetaData(
-			NodeTypeEnum nodeTypeEnum) {
-		return this.cacheMangerOperation.getTitanGenericDao().getByCriteria(nodeTypeEnum, null,
-				ComponentMetadataData.class);
-	}
+    /**
+     * the method retrives all nodes matching the given node type from the graph
+     *
+     * @param nodeTypeEnum
+     *            node type we want to lookup on the graph
+     * @return a list of retrieved nodes matching the given type or not found in
+     *         case no nodes were found or error in case of failure
+     */
+    private Either<List<ComponentMetadataData>, TitanOperationStatus> getAllComponentsMetaData(
+            NodeTypeEnum nodeTypeEnum) {
+        return this.cacheMangerOperation.getTitanGenericDao().getByCriteria(nodeTypeEnum, null,
+                ComponentMetadataData.class);
+    }
 
-	/**
-	 * the method retrieves the metadata from graph for the given id
-	 * 
-	 * @param uid
-	 *            the unique id of the component we want to retrieve
-	 * @param nodeTypeEnum
-	 *            the type of the recored we want to retrieve
-	 * @return the meta dat of the component or the error encountered during the
-	 *         get
-	 */
-	private Either<ComponentMetadataData, TitanOperationStatus> getComponentMetaData(String uid,
-			NodeTypeEnum nodeTypeEnum) {
-		return this.cacheMangerOperation.getTitanGenericDao().getNode(UniqueIdBuilder.getKeyByNodeType(nodeTypeEnum),
-				uid, ComponentMetadataData.class);
-	}
+    /**
+     * the method retrieves the metadata from graph for the given id
+     *
+     * @param uid
+     *            the unique id of the component we want to retrieve
+     * @param nodeTypeEnum
+     *            the type of the recored we want to retrieve
+     * @return the meta dat of the component or the error encountered during the
+     *         get
+     */
+    private Either<ComponentMetadataData, TitanOperationStatus> getComponentMetaData(String uid,
+            NodeTypeEnum nodeTypeEnum) {
+        return this.cacheMangerOperation.getTitanGenericDao().getNode(UniqueIdBuilder.getKeyByNodeType(nodeTypeEnum),
+                uid, ComponentMetadataData.class);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/catalog/CatalogComponent.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/catalog/CatalogComponent.java
index d051e0a..c74f22e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/catalog/CatalogComponent.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/catalog/CatalogComponent.java
@@ -1,7 +1,14 @@
 package org.openecomp.sdc.be.model.catalog;
 
+import com.google.common.collect.ImmutableList;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static java.util.Objects.requireNonNull;
+
 public class CatalogComponent {
 
     private String version;
@@ -15,6 +22,7 @@
     private String categoryNormalizedName;
     private String subCategoryNormalizedName;
     private String distributionStatus;
+    private List<String> tags;
 
     public String getCategoryNormalizedName() {
         return categoryNormalizedName;
@@ -96,12 +104,20 @@
         this.lifecycleState = lifecycleState;
     }
 
-	public String getDistributionStatus() {
-		return distributionStatus;
-	}
+    public String getDistributionStatus() {
+        return distributionStatus;
+    }
 
-	public void setDistributionStatus(String distributionStatus) {
-		this.distributionStatus = distributionStatus;
-	}
-    
+    public void setDistributionStatus(String distributionStatus) {
+        this.distributionStatus = distributionStatus;
+    }
+
+    public List<String> getTags() {
+        return tags == null ? Collections.emptyList() : ImmutableList.copyOf(tags);
+    }
+
+    public void setTags(List<String> tags) {
+        requireNonNull(tags);
+        this.tags = new ArrayList<>(tags);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.java
index 9286344..d943fb0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.java
@@ -20,47 +20,41 @@
 
 package org.openecomp.sdc.be.model.category;
 
-import java.io.Serializable;
+import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition;
+
 import java.util.ArrayList;
 import java.util.List;
 
-import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition;
+public class CategoryDefinition extends CategoryDataDefinition {
 
-public class CategoryDefinition extends CategoryDataDefinition implements Serializable {
+    private List<SubCategoryDefinition> subcategories;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 6552733796860992476L;
+    public CategoryDefinition() {
+        super();
+    }
 
-	List<SubCategoryDefinition> subcategories;
+    public CategoryDefinition(CategoryDataDefinition c) {
+        super(c);
+    }
 
-	public CategoryDefinition() {
-		super();
-	}
+    public List<SubCategoryDefinition> getSubcategories() {
+        return subcategories;
+    }
 
-	public CategoryDefinition(CategoryDataDefinition c) {
-		super(c);
-	}
+    public void setSubcategories(List<SubCategoryDefinition> subcategories) {
+        this.subcategories = subcategories;
+    }
 
-	public List<SubCategoryDefinition> getSubcategories() {
-		return subcategories;
-	}
+    public void addSubCategory(SubCategoryDefinition subcategory) {
+        if (subcategories == null) {
+            subcategories = new ArrayList<>();
+        }
+        subcategories.add(subcategory);
+    }
 
-	public void setSubcategories(List<SubCategoryDefinition> subcategories) {
-		this.subcategories = subcategories;
-	}
-
-	public void addSubCategory(SubCategoryDefinition subcategory) {
-		if (subcategories == null) {
-			subcategories = new ArrayList<SubCategoryDefinition>();
-		}
-		subcategories.add(subcategory);
-	}
-
-	@Override
-	public String toString() {
-		return super.toString() + " CategoryDefinition [subcategories=" + subcategories + "]";
-	}
+    @Override
+    public String toString() {
+        return super.toString() + " CategoryDefinition [subcategories=" + subcategories + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.java
index aeee0a8..8d83933 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.java
@@ -24,12 +24,12 @@
 
 public class GroupingDefinition extends GroupingDataDefinition {
 
-	public GroupingDefinition() {
-		super();
-	}
+    public GroupingDefinition() {
+        super();
+    }
 
-	public GroupingDefinition(GroupingDataDefinition g) {
-		super(g);
-	}
+    public GroupingDefinition(GroupingDataDefinition g) {
+        super(g);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.java
index 14559a1..c9ae3ac 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.java
@@ -20,41 +20,41 @@
 
 package org.openecomp.sdc.be.model.category;
 
+import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition;
+
 import java.util.ArrayList;
 import java.util.List;
 
-import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition;
-
 public class SubCategoryDefinition extends SubCategoryDataDefinition {
 
-	private List<GroupingDefinition> groupings;
+    private List<GroupingDefinition> groupings;
 
-	public SubCategoryDefinition() {
-		super();
-	}
+    public SubCategoryDefinition() {
+        super();
+    }
 
-	public SubCategoryDefinition(SubCategoryDataDefinition subCategory) {
-		super(subCategory);
-	}
+    public SubCategoryDefinition(SubCategoryDataDefinition subCategory) {
+        super(subCategory);
+    }
 
-	public List<GroupingDefinition> getGroupings() {
-		return groupings;
-	}
+    public List<GroupingDefinition> getGroupings() {
+        return groupings;
+    }
 
-	public void setGroupings(List<GroupingDefinition> groupingDefinitions) {
-		this.groupings = groupingDefinitions;
-	}
+    public void setGroupings(List<GroupingDefinition> groupingDefinitions) {
+        this.groupings = groupingDefinitions;
+    }
 
-	public void addGrouping(GroupingDefinition groupingDefinition) {
-		if (groupings == null) {
-			groupings = new ArrayList<GroupingDefinition>();
-		}
-		groupings.add(groupingDefinition);
-	}
+    public void addGrouping(GroupingDefinition groupingDefinition) {
+        if (groupings == null) {
+            groupings = new ArrayList<>();
+        }
+        groupings.add(groupingDefinition);
+    }
 
-	@Override
-	public String toString() {
-		return super.toString() + " SubCategoryDefinition [groupings=" + groupings + "]";
-	}
+    @Override
+    public String toString() {
+        return super.toString() + " SubCategoryDefinition [groupings=" + groupings + "]";
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.java
index 7f02684..f5f4d9f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.java
@@ -20,75 +20,66 @@
 
 package org.openecomp.sdc.be.model.heat;
 
-import org.openecomp.sdc.be.model.tosca.converters.HeatBooleanConverter;
-import org.openecomp.sdc.be.model.tosca.converters.HeatCommaDelimitedListConverter;
-import org.openecomp.sdc.be.model.tosca.converters.HeatJsonConverter;
-import org.openecomp.sdc.be.model.tosca.converters.HeatNumberConverter;
-import org.openecomp.sdc.be.model.tosca.converters.HeatStringConverter;
-import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
-import org.openecomp.sdc.be.model.tosca.validators.HeatBooleanValidator;
-import org.openecomp.sdc.be.model.tosca.validators.HeatCommaDelimitedListValidator;
-import org.openecomp.sdc.be.model.tosca.validators.HeatNumberValidator;
-import org.openecomp.sdc.be.model.tosca.validators.HeatStringValidator;
-import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
+import org.openecomp.sdc.be.model.tosca.converters.*;
+import org.openecomp.sdc.be.model.tosca.validators.*;
 
 public enum HeatParameterType {
 
-	STRING("string", HeatStringValidator.getInstance(), HeatStringConverter.getInstance()),
+    STRING("string", HeatStringValidator.getInstance(), HeatStringConverter.getInstance()),
 
-	BOOLEAN("boolean", HeatBooleanValidator.getInstance(), HeatBooleanConverter.getInstance()),
+    BOOLEAN("boolean", HeatBooleanValidator.getInstance(), HeatBooleanConverter.getInstance()),
 
-	NUMBER("number", HeatNumberValidator.getInstance(), HeatNumberConverter.getInstance()),
+    NUMBER("number", HeatNumberValidator.getInstance(), HeatNumberConverter.getInstance()),
 
-	JSON("json", HeatStringValidator.getInstance(), HeatJsonConverter.getInstance()),
+    JSON("json", HeatStringValidator.getInstance(), HeatJsonConverter.getInstance()),
 
-	COMMA_DELIMITED_LIST("comma_delimited_list", HeatCommaDelimitedListValidator.getInstance(),
-			HeatCommaDelimitedListConverter.getInstance());
+    COMMA_DELIMITED_LIST("comma_delimited_list", HeatCommaDelimitedListValidator.getInstance(),
+            HeatCommaDelimitedListConverter.getInstance());
 
-	private String type;
-	private PropertyTypeValidator validator;
-	private PropertyValueConverter converter;
+    private String type;
+    private PropertyTypeValidator validator;
+    private PropertyValueConverter converter;
 
-	HeatParameterType(String type, PropertyTypeValidator validator, PropertyValueConverter converter) {
-		this.type = type;
-		this.validator = validator;
-		this.converter = converter;
-	}
+    HeatParameterType(String type, PropertyTypeValidator validator, PropertyValueConverter converter) {
+        this.type = type;
+        this.validator = validator;
+        this.converter = converter;
+    }
 
-	public String getType() {
-		return type;
-	}
+    public String getType() {
+        return type;
+    }
 
-	public void setType(String type) {
-		this.type = type;
-	}
+    public void setType(String type) {
+        this.type = type;
+    }
 
-	public PropertyTypeValidator getValidator() {
-		return validator;
-	}
+    public PropertyTypeValidator getValidator() {
+        return validator;
+    }
 
-	public void setValidator(PropertyTypeValidator validator) {
-		this.validator = validator;
-	}
+    public void setValidator(PropertyTypeValidator validator) {
+        this.validator = validator;
+    }
 
-	public PropertyValueConverter getConverter() {
-		return converter;
-	}
+    public PropertyValueConverter getConverter() {
+        return converter;
+    }
 
-	public void setConverter(PropertyValueConverter converter) {
-		this.converter = converter;
-	}
+    public void setConverter(PropertyValueConverter converter) {
+        this.converter = converter;
+    }
 
-	public static HeatParameterType isValidType(String typeName) {
-		if (typeName == null) {
-			return null;
-		}
+    public static HeatParameterType isValidType(String typeName) {
+        if (typeName == null) {
+            return null;
+        }
 
-		for (HeatParameterType type : HeatParameterType.values()) {
-			if (type.getType().equals(typeName)) {
-				return type;
-			}
-		}
-		return null;
-	}
+        for (HeatParameterType type : HeatParameterType.values()) {
+            if (type.getType().equals(typeName)) {
+                return type;
+            }
+        }
+        return null;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeType.java
index c6157ba..7ac941e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeType.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeType.java
@@ -20,89 +20,79 @@
 
 package org.openecomp.sdc.be.model.jsontitan.datamodel;
 
+import org.openecomp.sdc.be.datatypes.elements.*;
+
 import java.util.List;
 import java.util.Map;
 
-import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
-
 public class NodeType extends ToscaElement{
 
-	public NodeType() {
-		super(ToscaElementTypeEnum.NodeType);
-	}
+    public NodeType() {
+        super(ToscaElementTypeEnum.NODE_TYPE);
+    }
 
-	private List<String> derivedFrom;
-	private List<String> derivedList;
-	
-	private Map<String, PropertyDataDefinition> attributes;
-	private Map<String, ListCapabilityDataDefinition> capabilties;
-	private Map<String, MapPropertiesDataDefinition> capabiltiesProperties;
-	private Map<String, ListRequirementDataDefinition> requirements;
-	private Map<String, InterfaceDataDefinition> interfaceArtifacts;
-	
-	
-	// will be used in future
-	// private Map<String, Map<String, Object>> other;
+    private List<String> derivedFrom;
+    private List<String> derivedList;
+    private Map<String, PropertyDataDefinition> attributes;
+    private Map<String, ListCapabilityDataDefinition> capabilties;
+    private Map<String, MapPropertiesDataDefinition> capabiltiesProperties;
+    private Map<String, ListRequirementDataDefinition> requirements;
+    private Map<String, InterfaceDataDefinition> interfaceArtifacts;
 
+    public List<String> getDerivedList() {
+        return derivedList;
+    }
 
-	public List<String> getDerivedList() {
-		return derivedList;
-	}
+    public void setDerivedList(List<String> derivedList) {
+        this.derivedList = derivedList;
+    }
 
-	public void setDerivedList(List<String> derivedList) {
-		this.derivedList = derivedList;
-	}
+    public List<String> getDerivedFrom() {
+        return derivedFrom;
+    }
 
-	public List<String> getDerivedFrom() {
-		return derivedFrom;
-	}
+    public void setDerivedFrom(List<String> derivedFrom) {
+        this.derivedFrom = derivedFrom;
+    }
 
-	public void setDerivedFrom(List<String> derivedFrom) {
-		this.derivedFrom = derivedFrom;
-	}
+    public Map<String, PropertyDataDefinition> getAttributes() {
+        return attributes;
+    }
 
-	public Map<String, PropertyDataDefinition> getAttributes() {
-		return attributes;
-	}
+    public void setAttributes(Map<String, PropertyDataDefinition> attributes) {
+        this.attributes = attributes;
+    }
 
-	public void setAttributes(Map<String, PropertyDataDefinition> attributes) {
-		this.attributes = attributes;
-	}
+    public Map<String, ListCapabilityDataDefinition> getCapabilties() {
+        return capabilties;
+    }
 
-	public Map<String, ListCapabilityDataDefinition> getCapabilties() {
-		return capabilties;
-	}
+    public void setCapabilties(Map<String, ListCapabilityDataDefinition> capabilties) {
+        this.capabilties = capabilties;
+    }
 
-	public void setCapabilties(Map<String, ListCapabilityDataDefinition> capabilties) {
-		this.capabilties = capabilties;
-	}
+    public Map<String, ListRequirementDataDefinition> getRequirements() {
+        return requirements;
+    }
 
-	public Map<String, ListRequirementDataDefinition> getRequirements() {
-		return requirements;
-	}
+    public void setRequirements(Map<String, ListRequirementDataDefinition> requirements) {
+        this.requirements = requirements;
+    }
 
-	public void setRequirements(Map<String, ListRequirementDataDefinition> requirements) {
-		this.requirements = requirements;
-	}
+    public Map<String, MapPropertiesDataDefinition> getCapabiltiesProperties() {
+        return capabiltiesProperties;
+    }
 
-	public Map<String, MapPropertiesDataDefinition> getCapabiltiesProperties() {
-		return capabiltiesProperties;
-	}
+    public void setCapabiltiesProperties(Map<String, MapPropertiesDataDefinition> capabiltiesProperties) {
+        this.capabiltiesProperties = capabiltiesProperties;
+    }
 
-	public void setCapabiltiesProperties(Map<String, MapPropertiesDataDefinition> capabiltiesProperties) {
-		this.capabiltiesProperties = capabiltiesProperties;
-	}
+    public Map<String, InterfaceDataDefinition> getInterfaceArtifacts() {
+        return interfaceArtifacts;
+    }
 
-	public Map<String, InterfaceDataDefinition> getInterfaceArtifacts() {
-		return interfaceArtifacts;
-	}
-
-	public void setInterfaceArtifacts(Map<String, InterfaceDataDefinition> interfaceArtifacts) {
-		this.interfaceArtifacts = interfaceArtifacts;
-	}
+    public void setInterfaceArtifacts(Map<String, InterfaceDataDefinition> interfaceArtifacts) {
+        this.interfaceArtifacts = interfaceArtifacts;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java
index 567258d..36d597e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java
@@ -20,239 +20,217 @@
 
 package org.openecomp.sdc.be.model.jsontitan.datamodel;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.apache.commons.collections.MapUtils;
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
-import org.openecomp.sdc.be.datatypes.elements.MapComponentInstanceExternalRefs;
-import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListCapabiltyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.*;
+import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
+import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
 import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
 
+import java.util.HashMap;
+import java.util.Map;
+
 public class TopologyTemplate extends ToscaElement{
 
-	public TopologyTemplate() {
-		super(ToscaElementTypeEnum.TopologyTemplate);
-	}
-	private Map<String, PropertyDataDefinition> inputs;
-	private Map<String, MapPropertiesDataDefinition> instInputs;
-	private Map<String, ? extends ToscaDataDefinition> heatParameters;
-	private Map<String, MapPropertiesDataDefinition> instAttributes;
-	private Map<String, MapPropertiesDataDefinition> instProperties;
-	private Map<String, GroupDataDefinition> groups;
-	private Map<String, PolicyDataDefinition> policies;
-	private Map<String, MapGroupsDataDefinition> instGroups;
-	private Map<String, ArtifactDataDefinition> serviceApiArtifacts;
-	private Map<String, ForwardingPathDataDefinition> forwardingPaths;
-	private Map<String, CompositionDataDefinition> compositions; 
+    public TopologyTemplate() {
+        super(ToscaElementTypeEnum.TOPOLOGY_TEMPLATE);
+    }
+    private Map<String, PropertyDataDefinition> inputs;
+    private Map<String, MapPropertiesDataDefinition> instInputs;
+    private Map<String, ? extends ToscaDataDefinition> heatParameters;
+    private Map<String, MapPropertiesDataDefinition> instAttributes;
+    private Map<String, MapPropertiesDataDefinition> instProperties;
+    private Map<String, GroupDataDefinition> groups;
+    private Map<String, PolicyDataDefinition> policies;
+    private Map<String, MapGroupsDataDefinition> instGroups;
+    private Map<String, ArtifactDataDefinition> serviceApiArtifacts;
+    private Map<String, ForwardingPathDataDefinition> forwardingPaths;
+    private Map<String, CompositionDataDefinition> compositions;
+    private Map<String, MapListCapabilityDataDefinition> calculatedCapabilities;
+    private Map<String, MapListRequirementDataDefinition> calculatedRequirements;
+    private Map<String, MapListCapabilityDataDefinition> fullfilledCapabilities;
+    private Map<String, MapListRequirementDataDefinition> fullfilledRequirements;
+    private Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties;
+    private Map<String, MapArtifactDataDefinition> instDeploymentArtifacts;
+    private Map<String, MapArtifactDataDefinition> instanceArtifacts;
+    
+    //Component Instances External References (instanceId -> ExternalRefsMap)
+    //-----------------------------------------------------------------------
+    private Map<String, MapComponentInstanceExternalRefs> mapComponentInstancesExternalRefs;
+    
+    public Map<String, MapComponentInstanceExternalRefs> getMapComponentInstancesExternalRefs() {
+        return this.mapComponentInstancesExternalRefs;
+    }
+    
+    public void setComponentInstancesExternalRefs(Map<String, MapComponentInstanceExternalRefs> mapComponentInstancesExternalRefs) {
+        this.mapComponentInstancesExternalRefs = mapComponentInstancesExternalRefs;
+    }
+    //-----------------------------------------------------------------------
 
-	private Map<String, MapListCapabiltyDataDefinition> calculatedCapabilities;
-	private Map<String, MapListRequirementDataDefinition> calculatedRequirements;
-	private Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilities;
-	private Map<String, MapListRequirementDataDefinition> fullfilledRequirements;
-	
-	private Map<String, MapCapabiltyProperty> calculatedCapabilitiesProperties;
-	
-	private Map<String, MapArtifactDataDefinition> instDeploymentArtifacts;
-	private Map<String, MapArtifactDataDefinition> instanceArtifacts;
-	private Map<String, InterfaceDataDefinition> interfaces;
 
-	//Component Instances External References (instanceId -> ExternalRefsMap)
-	//-----------------------------------------------------------------------
-	private Map<String, MapComponentInstanceExternalRefs> mapComponentInstancesExternalRefs;
-	public Map<String, MapComponentInstanceExternalRefs> getMapComponentInstancesExternalRefs() {
-		return this.mapComponentInstancesExternalRefs;
-	}
-	public void setComponentInstancesExternalRefs(Map<String, MapComponentInstanceExternalRefs> mapComponentInstancesExternalRefs) {
-		this.mapComponentInstancesExternalRefs = mapComponentInstancesExternalRefs;
-	}
-	//-----------------------------------------------------------------------
+    public Map<String, PropertyDataDefinition> getInputs() {
+        return inputs;
+    }
+    public void setInputs(Map<String, PropertyDataDefinition> inputs) {
+        this.inputs = inputs;
+    }
+    public Map<String, MapPropertiesDataDefinition> getInstInputs() {
+        return instInputs;
+    }
+    public void setInstInputs(Map<String, MapPropertiesDataDefinition> instInputs) {
+        this.instInputs = instInputs;
+    }
+    public Map<String, ? extends ToscaDataDefinition> getHeatParameters() {
+        return heatParameters;
+    }
+    public void setHeatParameters(Map<String, ? extends ToscaDataDefinition> heatParameters) {
+        this.heatParameters = heatParameters;
+    }
+    public Map<String, MapPropertiesDataDefinition> getInstAttributes() {
+        return instAttributes;
+    }
+    public void setInstAttributes(Map<String, MapPropertiesDataDefinition> instAttributes) {
+        this.instAttributes = instAttributes;
+    }
+    public Map<String, MapPropertiesDataDefinition> getInstProperties() {
+        return instProperties;
+    }
+    public void setInstProperties(Map<String, MapPropertiesDataDefinition> instProperties) {
+        this.instProperties = instProperties;
+    }
+    public Map<String, GroupDataDefinition> getGroups() {
+        return groups;
+    }
+    public void setGroups(Map<String, GroupDataDefinition> groups) {
+        this.groups = groups;
+    }
+    public Map<String, PolicyDataDefinition> getPolicies() {
+        return policies;
+    }
+    public void setPolicies(Map<String, PolicyDataDefinition> policies) {
+        this.policies = policies;
+    }
+    public Map<String, MapGroupsDataDefinition> getInstGroups() {
+        return instGroups;
+    }
+    public void setInstGroups(Map<String, MapGroupsDataDefinition> instGroups) {
+        this.instGroups = instGroups;
+    }
+    public Map<String, ArtifactDataDefinition> getServiceApiArtifacts() {
+        return serviceApiArtifacts;
+    }
+    public void setServiceApiArtifacts(Map<String, ArtifactDataDefinition> serviceApiArtifacts) {
+        this.serviceApiArtifacts = serviceApiArtifacts;
+    }
+    public Map<String, CompositionDataDefinition> getCompositions() {
+        return compositions;
+    }
+    public void setCompositions(Map<String, CompositionDataDefinition> compositions) {
+        this.compositions = compositions;
+    }
+    public Map<String, MapListCapabilityDataDefinition> getCalculatedCapabilities() {
+        return calculatedCapabilities;
+    }
+    public void setCalculatedCapabilities(Map<String, MapListCapabilityDataDefinition> calculatedCapabilities) {
+        this.calculatedCapabilities = calculatedCapabilities;
+    }
+    public Map<String, MapListRequirementDataDefinition> getCalculatedRequirements() {
+        return calculatedRequirements;
+    }
+    public void setCalculatedRequirements(Map<String, MapListRequirementDataDefinition> calculatedRequirements) {
+        this.calculatedRequirements = calculatedRequirements;
+    }
+    public Map<String, MapListCapabilityDataDefinition> getFullfilledCapabilities() {
+        return fullfilledCapabilities;
+    }
+    public void setFullfilledCapabilities(Map<String, MapListCapabilityDataDefinition> fullfilledCapabilities) {
+        this.fullfilledCapabilities = fullfilledCapabilities;
+    }
+    public Map<String, MapListRequirementDataDefinition> getFullfilledRequirements() {
+        return fullfilledRequirements;
+    }
+    public void setFullfilledRequirements(Map<String, MapListRequirementDataDefinition> fullfilledRequirements) {
+        this.fullfilledRequirements = fullfilledRequirements;
+    }
 
-	public Map<String, InterfaceDataDefinition> getInterfaces() {
-		return interfaces;
-	}
+    public Map<String, MapArtifactDataDefinition> getInstDeploymentArtifacts() {
+        return instDeploymentArtifacts;
+    }
+    public void setInstDeploymentArtifacts(Map<String, MapArtifactDataDefinition> instDeploymentArtifacts) {
+        this.instDeploymentArtifacts = instDeploymentArtifacts;
+    }
 
-	public void setInterfaces(Map<String, InterfaceDataDefinition> interfaces) {
-		this.interfaces = interfaces;
-	}
+    public Map<String, MapCapabilityProperty> getCalculatedCapabilitiesProperties() {
+        return calculatedCapabilitiesProperties;
+    }
+    public void setCalculatedCapabilitiesProperties(Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties) {
+        this.calculatedCapabilitiesProperties = calculatedCapabilitiesProperties;
+    }
 
-	public Map<String, PropertyDataDefinition> getInputs() {
-		return inputs;
-	}
-	public void setInputs(Map<String, PropertyDataDefinition> inputs) {
-		this.inputs = inputs;
-	}
-	public Map<String, MapPropertiesDataDefinition> getInstInputs() {
-		return instInputs;
-	}
-	public void setInstInputs(Map<String, MapPropertiesDataDefinition> instInputs) {
-		this.instInputs = instInputs;
-	}
-	public Map<String, ? extends ToscaDataDefinition> getHeatParameters() {
-		return heatParameters;
-	}
-	public void setHeatParameters(Map<String, ? extends ToscaDataDefinition> heatParameters) {
-		this.heatParameters = heatParameters;
-	}
-	public Map<String, MapPropertiesDataDefinition> getInstAttributes() {
-		return instAttributes;
-	}
-	public void setInstAttributes(Map<String, MapPropertiesDataDefinition> instAttributes) {
-		this.instAttributes = instAttributes;
-	}
-	public Map<String, MapPropertiesDataDefinition> getInstProperties() {
-		return instProperties;
-	}
-	public void setInstProperties(Map<String, MapPropertiesDataDefinition> instProperties) {
-		this.instProperties = instProperties;
-	}
-	public Map<String, GroupDataDefinition> getGroups() {
-		return groups;
-	}
-	public void setGroups(Map<String, GroupDataDefinition> groups) {
-		this.groups = groups;
-	}
-	public Map<String, PolicyDataDefinition> getPolicies() {
-		return policies;
-	}
-	public void setPolicies(Map<String, PolicyDataDefinition> policies) {
-		this.policies = policies;
-	}
-	public Map<String, MapGroupsDataDefinition> getInstGroups() {
-		return instGroups;
-	}
-	public void setInstGroups(Map<String, MapGroupsDataDefinition> instGroups) {
-		this.instGroups = instGroups;
-	}
-	public Map<String, ArtifactDataDefinition> getServiceApiArtifacts() {
-		return serviceApiArtifacts;
-	}
-	public void setServiceApiArtifacts(Map<String, ArtifactDataDefinition> serviceApiArtifacts) {
-		this.serviceApiArtifacts = serviceApiArtifacts;
-	}
-	public Map<String, CompositionDataDefinition> getCompositions() {
-		return compositions;
-	}
-	public void setCompositions(Map<String, CompositionDataDefinition> compositions) {
-		this.compositions = compositions;
-	}
-	public Map<String, MapListCapabiltyDataDefinition> getCalculatedCapabilities() {
-		return calculatedCapabilities;
-	}
-	public void setCalculatedCapabilities(Map<String, MapListCapabiltyDataDefinition> calculatedCapabilities) {
-		this.calculatedCapabilities = calculatedCapabilities;
-	}
-	public Map<String, MapListRequirementDataDefinition> getCalculatedRequirements() {
-		return calculatedRequirements;
-	}
-	public void setCalculatedRequirements(Map<String, MapListRequirementDataDefinition> calculatedRequirements) {
-		this.calculatedRequirements = calculatedRequirements;
-	}
-	public Map<String, MapListCapabiltyDataDefinition> getFullfilledCapabilities() {
-		return fullfilledCapabilities;
-	}
-	public void setFullfilledCapabilities(Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilities) {
-		this.fullfilledCapabilities = fullfilledCapabilities;
-	}
-	public Map<String, MapListRequirementDataDefinition> getFullfilledRequirements() {
-		return fullfilledRequirements;
-	}
-	public void setFullfilledRequirements(Map<String, MapListRequirementDataDefinition> fullfilledRequirements) {
-		this.fullfilledRequirements = fullfilledRequirements;
-	}
-	
-	public Map<String, MapArtifactDataDefinition> getInstDeploymentArtifacts() {
-		return instDeploymentArtifacts;
-	}
-	public void setInstDeploymentArtifacts(Map<String, MapArtifactDataDefinition> instDeploymentArtifacts) {
-		this.instDeploymentArtifacts = instDeploymentArtifacts;
-	}
-	
-	public Map<String, MapCapabiltyProperty> getCalculatedCapabilitiesProperties() {
-		return calculatedCapabilitiesProperties;
-	}
-	public void setCalculatedCapabilitiesProperties(Map<String, MapCapabiltyProperty> calculatedCapabilitiesProperties) {
-		this.calculatedCapabilitiesProperties = calculatedCapabilitiesProperties;
-	}
-	
-	public Map<String, MapArtifactDataDefinition> getInstanceArtifacts() {
-		return instanceArtifacts;
-	}
-	public void setInstanceArtifacts(Map<String, MapArtifactDataDefinition> instanceArtifacts) {
-		this.instanceArtifacts = instanceArtifacts;
-	}
+    public Map<String, MapArtifactDataDefinition> getInstanceArtifacts() {
+        return instanceArtifacts;
+    }
+    public void setInstanceArtifacts(Map<String, MapArtifactDataDefinition> instanceArtifacts) {
+        this.instanceArtifacts = instanceArtifacts;
+    }
 
-	public Map<String, ForwardingPathDataDefinition> getForwardingPaths() {
-		return forwardingPaths;
-	}
+    public Map<String, ForwardingPathDataDefinition> getForwardingPaths() {
+        return forwardingPaths;
+    }
 
-	public void setForwardingPaths(Map<String, ForwardingPathDataDefinition> forwardingPaths) {
-		this.forwardingPaths = forwardingPaths;
-	}
+    public void setForwardingPaths(Map<String, ForwardingPathDataDefinition> forwardingPaths) {
+        this.forwardingPaths = forwardingPaths;
+    }
 
-	/**
-	 * Adds component instance to composition of topology template
-	 * Note that component instance will be overrided in case if the topology template already contains a component instance with the same name
-	 * @param componentInstance
-	 */
-	public void addComponentInstance(ComponentInstanceDataDefinition componentInstance){
-		if(getCompositions() == null){
-			compositions = new HashMap<>();
-		}
-		if(MapUtils.isEmpty(getCompositions())){
-			compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), new CompositionDataDefinition());
-		}
-		if(MapUtils.isEmpty(getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).getComponentInstances())){
-			getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).setComponentInstances(new HashMap<>());
-		}
-		getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).getComponentInstances().put(componentInstance.getUniqueId(), componentInstance);
-	}
-	/**
-	 * Returns map of component instances from composition
-	 * @return
-	 */
-	public Map<String, ComponentInstanceDataDefinition> getComponentInstances() {
-		Map<String, ComponentInstanceDataDefinition> instances = null;
-		if(getCompositions() != null && getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()) != null ){
-			instances = getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).getComponentInstances();
-		}
-		return instances;
-	}
-	
-	
-	/**
-	 * Sets map of component instances to composition of topology template
-	 * Note that component instances will be overrided in case if the topology template already contains a component instances
-	 * @param instances
-	 */
-	public void setComponentInstances(Map<String, ComponentInstanceDataDefinition> instances) {
-		if(getCompositions() == null){
-			compositions = new HashMap<>();
-		}
-		if(MapUtils.isEmpty(getCompositions())){
-			compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), new CompositionDataDefinition());
-		}
-		getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).setComponentInstances(instances);
-	}
-	public Map<String, RelationshipInstDataDefinition> getRelations() {
-		Map<String, RelationshipInstDataDefinition> relations = null;
-		if( getCompositions() != null && getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()) != null ){
-			relations = getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).getRelations();
-		}
-		return relations;
-	}
+    /**
+     * Adds component instance to composition of topology template
+     * Note that component instance will be overrided in case if the topology template already contains a component instance with the same name
+     * @param componentInstance
+     */
+    public void addComponentInstance(ComponentInstanceDataDefinition componentInstance){
+        if(getCompositions() == null){
+            compositions = new HashMap<>();
+        }
+        if(MapUtils.isEmpty(getCompositions())){
+            compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), new CompositionDataDefinition());
+        }
+        if(MapUtils.isEmpty(getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).getComponentInstances())){
+            getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).setComponentInstances(new HashMap<>());
+        }
+        getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).getComponentInstances().put(componentInstance.getUniqueId(), componentInstance);
+    }
+    /**
+     * Returns map of component instances from composition
+     * @return
+     */
+    public Map<String, ComponentInstanceDataDefinition> getComponentInstances() {
+        Map<String, ComponentInstanceDataDefinition> instances = null;
+        if(getCompositions() != null && getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()) != null ){
+            instances = getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).getComponentInstances();
+        }
+        return instances;
+    }
+
+
+    /**
+     * Sets map of component instances to composition of topology template
+     * Note that component instances will be overrided in case if the topology template already contains a component instances
+     * @param instances
+     */
+    public void setComponentInstances(Map<String, ComponentInstanceDataDefinition> instances) {
+        if(getCompositions() == null){
+            compositions = new HashMap<>();
+        }
+        if(MapUtils.isEmpty(getCompositions())){
+            compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), new CompositionDataDefinition());
+        }
+        getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).setComponentInstances(instances);
+    }
+    public Map<String, RelationshipInstDataDefinition> getRelations() {
+        Map<String, RelationshipInstDataDefinition> relations = null;
+        if( getCompositions() != null && getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()) != null ){
+            relations = getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue()).getRelations();
+        }
+        return relations;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElement.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElement.java
index 90b32c6..0f0c63f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElement.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElement.java
@@ -20,11 +20,6 @@
 
 package org.openecomp.sdc.be.model.jsontitan.datamodel;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
@@ -36,262 +31,284 @@
 import org.openecomp.sdc.be.model.jsontitan.operations.NodeTypeOperation;
 import org.slf4j.MDC;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
 public abstract class ToscaElement {
-	
-	protected Map<String, Object> metadata;
-	protected List<CategoryDefinition> categories;
-	protected Map<String, ArtifactDataDefinition> toscaArtifacts;
-	private Map<String, ArtifactDataDefinition> artifacts;
-	private Map<String, ArtifactDataDefinition> deploymentArtifacts;
-	private Map<String, AdditionalInfoParameterDataDefinition> additionalInformation;
-	private Map<String, PropertyDataDefinition> properties;
-	
-	protected ToscaElementTypeEnum toscaType;
-	// User
-	private String creatorUserId;
-	private String creatorFullName;
-	private String lastUpdaterUserId;
-	private String lastUpdaterFullName;
 
-	private Map<String, String> allVersions;
-	
-	public ToscaElement(ToscaElementTypeEnum toscaType){
-		this.toscaType = toscaType;
-	}
-	
-	public Map<String, Object> getMetadata() {
-		return metadata;
-	}
+    protected Map<String, Object> metadata;
+    protected List<CategoryDefinition> categories;
+    protected Map<String, ArtifactDataDefinition> toscaArtifacts;
+    private Map<String, ArtifactDataDefinition> artifacts;
+    private Map<String, ArtifactDataDefinition> deploymentArtifacts;
+    private Map<String, AdditionalInfoParameterDataDefinition> additionalInformation;
+    private Map<String, PropertyDataDefinition> properties;
 
-	public void setMetadata(Map<String, Object> metadata) {
-		this.metadata = metadata;
-	}
+    protected ToscaElementTypeEnum toscaType;
+    // User
+    private String creatorUserId;
+    private String creatorFullName;
+    private String lastUpdaterUserId;
+    private String lastUpdaterFullName;
 
-	public List<CategoryDefinition> getCategories() {
-		return categories;
-	}
+    private Map<String, String> allVersions;
 
-	public void setCategories(List<CategoryDefinition> categories) {
-		this.categories = categories;
-	}
-	public Map<String, ArtifactDataDefinition> getToscaArtifacts() {
-		return toscaArtifacts;
-	}
+    public ToscaElement(ToscaElementTypeEnum toscaType){
+        this.toscaType = toscaType;
+    }
 
-	public void setToscaArtifacts(Map<String, ArtifactDataDefinition> toscaArtifacts) {
-		this.toscaArtifacts = toscaArtifacts;
-	}
+    public Map<String, Object> getMetadata() {
+        return metadata;
+    }
 
-	public ToscaElementTypeEnum getToscaType() {
-		return toscaType;
-	}
+    public void setMetadata(Map<String, Object> metadata) {
+        this.metadata = metadata;
+    }
 
-	public void setToscaType(ToscaElementTypeEnum toscaType) {
-		this.toscaType = toscaType;
-	}
-	public Map<String, ArtifactDataDefinition> getArtifacts() {
-		return artifacts;
-	}
+    public List<CategoryDefinition> getCategories() {
+        return categories;
+    }
 
-	public void setArtifacts(Map<String, ArtifactDataDefinition> artifacts) {
-		this.artifacts = artifacts;
-	}
+    public void setCategories(List<CategoryDefinition> categories) {
+        this.categories = categories;
+    }
+    public Map<String, ArtifactDataDefinition> getToscaArtifacts() {
+        return toscaArtifacts;
+    }
 
-	public Map<String, ArtifactDataDefinition> getDeploymentArtifacts() {
-		return deploymentArtifacts;
-	}
+    public void setToscaArtifacts(Map<String, ArtifactDataDefinition> toscaArtifacts) {
+        this.toscaArtifacts = toscaArtifacts;
+    }
 
-	public void setDeploymentArtifacts(Map<String, ArtifactDataDefinition> deploymentArtifacts) {
-		this.deploymentArtifacts = deploymentArtifacts;
-	}
-	public Map<String, AdditionalInfoParameterDataDefinition> getAdditionalInformation() {
-		return additionalInformation;
-	}
-	public void setAdditionalInformation(Map<String, AdditionalInfoParameterDataDefinition> additionalInformation) {
-		this.additionalInformation = additionalInformation;
-	}
-	public Map<String, PropertyDataDefinition> getProperties() {
-		return properties;
-	}
-	public void setProperties(Map<String, PropertyDataDefinition> properties) {
-		this.properties = properties;
-	}
+    public ToscaElementTypeEnum getToscaType() {
+        return toscaType;
+    }
 
-	public Map<String, String> getAllVersions() {
-		return allVersions;
-	}
+    public void setToscaType(ToscaElementTypeEnum toscaType) {
+        this.toscaType = toscaType;
+    }
+    public Map<String, ArtifactDataDefinition> getArtifacts() {
+        return artifacts;
+    }
 
-	public void setAllVersions(Map<String, String> allVersions) {
-		this.allVersions = allVersions;
-	}
+    public void setArtifacts(Map<String, ArtifactDataDefinition> artifacts) {
+        this.artifacts = artifacts;
+    }
 
-	// metadata properties
-	// ----------------------------
-	public Object getMetadataValue(JsonPresentationFields name) {
-		return getMetadataValueOrDefault(name, null);
-	}
+    public Map<String, ArtifactDataDefinition> getDeploymentArtifacts() {
+        return deploymentArtifacts;
+    }
 
-	public Object getMetadataValueOrDefault(JsonPresentationFields name, Object defaultVal) {
-		if (metadata != null) {
-			return metadata.getOrDefault(name.getPresentation(), defaultVal);
-		}
-		return null;
-	}
+    public void setDeploymentArtifacts(Map<String, ArtifactDataDefinition> deploymentArtifacts) {
+        this.deploymentArtifacts = deploymentArtifacts;
+    }
+    public Map<String, AdditionalInfoParameterDataDefinition> getAdditionalInformation() {
+        return additionalInformation;
+    }
+    public void setAdditionalInformation(Map<String, AdditionalInfoParameterDataDefinition> additionalInformation) {
+        this.additionalInformation = additionalInformation;
+    }
+    public Map<String, PropertyDataDefinition> getProperties() {
+        return properties;
+    }
+    public void setProperties(Map<String, PropertyDataDefinition> properties) {
+        this.properties = properties;
+    }
 
-	public void setMetadataValue(JsonPresentationFields name, Object value) {
-		if (metadata == null) {
-			metadata = new HashMap<String, Object>();
-		}
-		metadata.put(name.getPresentation(), value);
+    public Map<String, String> getAllVersions() {
+        return allVersions;
+    }
 
-	}
-	// --------------------
-	public String getUUID() {
-		return (String) getMetadataValue(JsonPresentationFields.UUID);
-	}
+    public void setAllVersions(Map<String, String> allVersions) {
+        this.allVersions = allVersions;
+    }
 
-	public void setUUID(String uuid) {
-		setMetadataValue(JsonPresentationFields.UUID, uuid);
-	}
+    // metadata properties
+    // ----------------------------
+    public Object getMetadataValue(JsonPresentationFields name) {
+        return getMetadataValueOrDefault(name, null);
+    }
 
-	public String getVersion() {
-		return (String) getMetadataValue(JsonPresentationFields.VERSION);
-	}
+    public Object getMetadataValueOrDefault(JsonPresentationFields name, Object defaultVal) {
+        if (metadata != null) {
+            return metadata.getOrDefault(name.getPresentation(), defaultVal);
+        }
+        return null;
+    }
 
-	public String getNormalizedName() {
-		return (String) getMetadataValue(JsonPresentationFields.NORMALIZED_NAME);
-	}
+    public void setMetadataValue(JsonPresentationFields name, Object value) {
+        if (metadata == null) {
+            metadata = new HashMap<>();
+        }
+        metadata.put(name.getPresentation(), value);
 
-	public void setNormalizedName(String normaliseComponentName) {
-		setMetadataValue(JsonPresentationFields.NORMALIZED_NAME, normaliseComponentName);
-	}
+    }
+    // --------------------
+    public String getUUID() {
+        return (String) getMetadataValue(JsonPresentationFields.UUID);
+    }
 
-	public String getName() {
-		return (String) getMetadataValue(JsonPresentationFields.NAME);
-	}
+    public void setUUID(String uuid) {
+        setMetadataValue(JsonPresentationFields.UUID, uuid);
+    }
 
-	public String getSystemName() {
-		return (String) getMetadataValue(JsonPresentationFields.SYSTEM_NAME);
-	}
-	public void setSystemName(String systemName) {
-		setMetadataValue(JsonPresentationFields.SYSTEM_NAME, systemName);
-	}
+    public String getVersion() {
+        return (String) getMetadataValue(JsonPresentationFields.VERSION);
+    }
 
-	public void setLifecycleState(LifecycleStateEnum state) {
-		if(state != null)
-			setMetadataValue(JsonPresentationFields.LIFECYCLE_STATE, state.name());
-	}
+    public String getNormalizedName() {
+        return (String) getMetadataValue(JsonPresentationFields.NORMALIZED_NAME);
+    }
 
-	public LifecycleStateEnum getLifecycleState() {
-		return LifecycleStateEnum.findState( (String) getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
-	}
+    public void setNormalizedName(String normaliseComponentName) {
+        setMetadataValue(JsonPresentationFields.NORMALIZED_NAME, normaliseComponentName);
+    }
 
-	public Long getCreationDate() {
-		return (Long) getMetadataValue(JsonPresentationFields.CREATION_DATE);
-	}
+    public String getName() {
+        return (String) getMetadataValue(JsonPresentationFields.NAME);
+    }
 
-	public void setCreationDate(Long currentDate) {
-		setMetadataValue(JsonPresentationFields.CREATION_DATE, currentDate);
-	}
+    public String getSystemName() {
+        return (String) getMetadataValue(JsonPresentationFields.SYSTEM_NAME);
+    }
+    public void setSystemName(String systemName) {
+        setMetadataValue(JsonPresentationFields.SYSTEM_NAME, systemName);
+    }
 
-	public void setLastUpdateDate(Long currentDate) {
-		setMetadataValue(JsonPresentationFields.LAST_UPDATE_DATE, currentDate);
-	}
-	public Long getLastUpdateDate() {
-		return (Long) getMetadataValue(JsonPresentationFields.LAST_UPDATE_DATE);
-	}
+    public void setLifecycleState(LifecycleStateEnum state) {
+        if(state != null)
+            setMetadataValue(JsonPresentationFields.LIFECYCLE_STATE, state.name());
+    }
 
-	public String getUniqueId() {
-		return (String) getMetadataValue(JsonPresentationFields.UNIQUE_ID);
-	}
-	public void setUniqueId(String uniqueId) {
-		 setMetadataValue(JsonPresentationFields.UNIQUE_ID, uniqueId);
-	}
+    public LifecycleStateEnum getLifecycleState() {
+        return LifecycleStateEnum.findState( (String) getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
+    }
 
-	public void setHighestVersion(Boolean isHighest) {
-		 setMetadataValue(JsonPresentationFields.HIGHEST_VERSION, isHighest);
-		
-	}
-	public Boolean isHighestVersion() {
-		return (Boolean) getMetadataValue(JsonPresentationFields.HIGHEST_VERSION);
-		
-	}
-	public ResourceTypeEnum getResourceType() {
-		String resourceType = (String) getMetadataValue(JsonPresentationFields.RESOURCE_TYPE);
-		return resourceType != null ? ResourceTypeEnum.valueOf(resourceType) : null;
-	}
+    public Long getCreationDate() {
+        return (Long) getMetadataValue(JsonPresentationFields.CREATION_DATE);
+    }
 
-	public void setResourceType(ResourceTypeEnum resourceType) {
-		if(resourceType != null)
-			setMetadataValue(JsonPresentationFields.RESOURCE_TYPE, resourceType.name());
-	}
-	
-	public ComponentTypeEnum getComponentType() {
-		return ComponentTypeEnum.valueOf((String) getMetadataValue(JsonPresentationFields.COMPONENT_TYPE));
-	}
+    public void setCreationDate(Long currentDate) {
+        setMetadataValue(JsonPresentationFields.CREATION_DATE, currentDate);
+    }
 
-	public void setComponentType(ComponentTypeEnum componentType) {
-		if(componentType != null)
-			setMetadataValue(JsonPresentationFields.COMPONENT_TYPE, componentType.name());
-	}
-	
-	public String getDerivedFromGenericType(){
-		return (String) getMetadataValue(JsonPresentationFields.DERIVED_FROM_GENERIC_TYPE);
-	}
-	
-	public void setDerivedFromGenericType(String derivedFromGenericType){
-		setMetadataValue(JsonPresentationFields.DERIVED_FROM_GENERIC_TYPE, derivedFromGenericType);
-	}
-	
-	public String getDerivedFromGenericVersion(){
-		return (String) getMetadataValue(JsonPresentationFields.DERIVED_FROM_GENERIC_VERSION);
-	}
-	
-	public void setDerivedFromGenericVersion(String derivedFromGenericVersion){
-		setMetadataValue(JsonPresentationFields.DERIVED_FROM_GENERIC_VERSION, derivedFromGenericVersion);
-	}
+    public void setLastUpdateDate(Long currentDate) {
+        setMetadataValue(JsonPresentationFields.LAST_UPDATE_DATE, currentDate);
+    }
+    public Long getLastUpdateDate() {
+        return (Long) getMetadataValue(JsonPresentationFields.LAST_UPDATE_DATE);
+    }
 
+    public String getUniqueId() {
+        return (String) getMetadataValue(JsonPresentationFields.UNIQUE_ID);
+    }
+    public void setUniqueId(String uniqueId) {
+         setMetadataValue(JsonPresentationFields.UNIQUE_ID, uniqueId);
+    }
 
-	public String getCreatorUserId() {
-		return creatorUserId;
-	}
+    public void setHighestVersion(Boolean isHighest) {
+         setMetadataValue(JsonPresentationFields.HIGHEST_VERSION, isHighest);
 
-	public void setCreatorUserId(String creatorUserId) {
-		this.creatorUserId = creatorUserId;
-	}
+    }
+    public Boolean isHighestVersion() {
+        return (Boolean) getMetadataValue(JsonPresentationFields.HIGHEST_VERSION);
 
-	public String getCreatorFullName() {
-		return creatorFullName;
-	}
+    }
+    public ResourceTypeEnum getResourceType() {
+        String resourceType = (String) getMetadataValue(JsonPresentationFields.RESOURCE_TYPE);
+        return resourceType != null ? ResourceTypeEnum.valueOf(resourceType) : null;
+    }
 
-	public void setCreatorFullName(String creatorFullName) {
-		this.creatorFullName = creatorFullName;
-	}
+    public void setResourceType(ResourceTypeEnum resourceType) {
+        if(resourceType != null)
+            setMetadataValue(JsonPresentationFields.RESOURCE_TYPE, resourceType.name());
+    }
 
-	public String getLastUpdaterUserId() {
-		return lastUpdaterUserId;
-	}
+    public ComponentTypeEnum getComponentType() {
+        return ComponentTypeEnum.valueOf((String) getMetadataValue(JsonPresentationFields.COMPONENT_TYPE));
+    }
 
-	public void setLastUpdaterUserId(String lastUpdaterUserId) {
-		this.lastUpdaterUserId = lastUpdaterUserId;
-	}
+    public void setComponentType(ComponentTypeEnum componentType) {
+        if(componentType != null)
+            setMetadataValue(JsonPresentationFields.COMPONENT_TYPE, componentType.name());
+    }
 
-	public String getLastUpdaterFullName() {
-		return lastUpdaterFullName;
-	}
+    public String getDerivedFromGenericType(){
+        return (String) getMetadataValue(JsonPresentationFields.DERIVED_FROM_GENERIC_TYPE);
+    }
 
-	public void setLastUpdaterFullName(String lastUpdaterFullName) {
-		this.lastUpdaterFullName = lastUpdaterFullName;
-	}
+    public void setDerivedFromGenericType(String derivedFromGenericType){
+        setMetadataValue(JsonPresentationFields.DERIVED_FROM_GENERIC_TYPE, derivedFromGenericType);
+    }
 
-	public void generateUUID() {
-		String prevUUID = getUUID();
-		String version = getVersion();
-		if ((prevUUID == null && NodeTypeOperation.uuidNormativeNewVersion.matcher(version).matches()) || NodeTypeOperation.uuidNewVersion.matcher(version).matches()) {
-			UUID uuid = UUID.randomUUID();
-			setUUID(uuid.toString());
-			MDC.put("serviceInstanceID", uuid.toString());
-		}
-	}
+    public String getDerivedFromGenericVersion(){
+        return (String) getMetadataValue(JsonPresentationFields.DERIVED_FROM_GENERIC_VERSION);
+    }
+
+    public void setDerivedFromGenericVersion(String derivedFromGenericVersion){
+        setMetadataValue(JsonPresentationFields.DERIVED_FROM_GENERIC_VERSION, derivedFromGenericVersion);
+    }
+
+    public Boolean isArchived() { return (Boolean) getMetadataValue(JsonPresentationFields.IS_ARCHIVED); }
+
+    public void setArchived(Boolean archived) { setMetadataValue(JsonPresentationFields.IS_ARCHIVED, archived); }
+
+    public Long getArchiveTime() {
+        Object archiveTime = getMetadataValue(JsonPresentationFields.ARCHIVE_TIME);
+        if (archiveTime instanceof Integer){
+            return new Long((Integer)getMetadataValue(JsonPresentationFields.ARCHIVE_TIME));
+        }
+        return (Long)archiveTime;
+    }
+
+    public void setArchiveTime(Long archiveTime) { setMetadataValue(JsonPresentationFields.ARCHIVE_TIME, archiveTime); }
+
+    public Boolean isVspArchived() { return (Boolean) getMetadataValue(JsonPresentationFields.IS_VSP_ARCHIVED); }
+
+    public void setVspArchived(Boolean vspArchived) { setMetadataValue(JsonPresentationFields.IS_VSP_ARCHIVED, vspArchived); }
+
+    public String getCreatorUserId() {
+        return creatorUserId;
+    }
+
+    public void setCreatorUserId(String creatorUserId) {
+        this.creatorUserId = creatorUserId;
+    }
+
+    public String getCreatorFullName() {
+        return creatorFullName;
+    }
+
+    public void setCreatorFullName(String creatorFullName) {
+        this.creatorFullName = creatorFullName;
+    }
+
+    public String getLastUpdaterUserId() {
+        return lastUpdaterUserId;
+    }
+
+    public void setLastUpdaterUserId(String lastUpdaterUserId) {
+        this.lastUpdaterUserId = lastUpdaterUserId;
+    }
+
+    public String getLastUpdaterFullName() {
+        return lastUpdaterFullName;
+    }
+
+    public void setLastUpdaterFullName(String lastUpdaterFullName) {
+        this.lastUpdaterFullName = lastUpdaterFullName;
+    }
+
+    public void generateUUID() {
+        String prevUUID = getUUID();
+        String version = getVersion();
+        if ((prevUUID == null && NodeTypeOperation.uuidNormativeNewVersion.matcher(version).matches()) || NodeTypeOperation.uuidNewVersion.matcher(version).matches()) {
+            UUID uuid = UUID.randomUUID();
+            setUUID(uuid.toString());
+            MDC.put("serviceInstanceID", uuid.toString());
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElementTypeEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElementTypeEnum.java
index 1dc7532..3ee492b 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElementTypeEnum.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElementTypeEnum.java
@@ -23,27 +23,27 @@
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 
 public enum ToscaElementTypeEnum {
-	NodeType("node_type"),
-	TopologyTemplate("topology_template");
-	
-	String value;
-	private ToscaElementTypeEnum(String value){
-		this.value = value;
-	}
-	
-	public static  VertexTypeEnum getVertexTypeByToscaType(ToscaElementTypeEnum toscaType ){
-		switch ( toscaType ){
-		case NodeType :
-			return VertexTypeEnum.NODE_TYPE;
-		case TopologyTemplate :
-			return VertexTypeEnum.TOPOLOGY_TEMPLATE;
-		default :
-			return  null;
-		}
-	}
+    NODE_TYPE("node_type"),
+    TOPOLOGY_TEMPLATE("topology_template");
 
-	public String getValue() {
-		return value;
-	}
-	
+    String value;
+    private ToscaElementTypeEnum(String value){
+        this.value = value;
+    }
+
+    public static  VertexTypeEnum getVertexTypeByToscaType(ToscaElementTypeEnum toscaType ){
+        switch ( toscaType ){
+        case NODE_TYPE :
+            return VertexTypeEnum.NODE_TYPE;
+        case TOPOLOGY_TEMPLATE :
+            return VertexTypeEnum.TOPOLOGY_TEMPLATE;
+        default :
+            return  null;
+        }
+    }
+
+    public String getValue() {
+        return value;
+    }
+
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/enums/JsonConstantKeysEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/enums/JsonConstantKeysEnum.java
index 0a10a3a..2a4496e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/enums/JsonConstantKeysEnum.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/enums/JsonConstantKeysEnum.java
@@ -21,22 +21,22 @@
 package org.openecomp.sdc.be.model.jsontitan.enums;
 
 public enum JsonConstantKeysEnum {
-	
-	COMPOSITION("composition"),
-	CAPABILITIES("capabilities"),
-	REQUIREMENTS("requirements"),
-	PROPERTIES("properties"),
-	INPUTS("inputs"),
-	GROUPS("groups"),
-	INSTANCE_PROPERIES("instanceProperties");
-	
-	private String value;
-	
-	private JsonConstantKeysEnum(String value) {
-		this.value = value;
-	}
-	
-	public String getValue() {
-		return value;
-	}
+
+    COMPOSITION("composition"),
+    CAPABILITIES("capabilities"),
+    REQUIREMENTS("requirements"),
+    PROPERTIES("properties"),
+    INPUTS("inputs"),
+    GROUPS("groups"),
+    INSTANCE_PROPERIES("instanceProperties");
+
+    private String value;
+
+    private JsonConstantKeysEnum(String value) {
+        this.value = value;
+    }
+
+    public String getValue() {
+        return value;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArchiveOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArchiveOperation.java
new file mode 100644
index 0000000..f4033a2
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArchiveOperation.java
@@ -0,0 +1,284 @@
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import fj.data.Either;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.model.LifecycleStateEnum;
+import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
+import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.openecomp.sdc.be.model.jsontitan.operations.ArchiveOperation.Action.ARCHIVE;
+import static org.openecomp.sdc.be.model.jsontitan.operations.ArchiveOperation.Action.RESTORE;
+
+/**
+ * Created by yavivi on 25/03/2018.
+ */
+@Component
+public class ArchiveOperation extends BaseOperation {
+
+    private static final Logger log = Logger.getLogger(ArchiveOperation.class.getName());
+
+    @Autowired
+    private IGraphLockOperation graphLockOperation;
+
+    public enum Action {
+        ARCHIVE, RESTORE;
+    }
+
+    public ArchiveOperation(TitanDao titanDao, IGraphLockOperation graphLockOperation){
+        this.titanDao = titanDao;
+        this.graphLockOperation = graphLockOperation;
+    }
+
+    public Either<List<String>, ActionStatus> archiveComponent(String componentId) {
+        final Either<GraphVertex, TitanOperationStatus> vertexResult = this.titanDao.getVertexById(componentId);
+        if (vertexResult.isLeft()){
+            return doAction(ARCHIVE, vertexResult.left().value());
+        } else {
+            return Either.right(onError(ARCHIVE.name(), componentId, vertexResult.right().value()));
+        }
+    }
+
+    public Either<List<String>, ActionStatus> restoreComponent(String componentId) {
+        final Either<GraphVertex, TitanOperationStatus> vertexResult = this.titanDao.getVertexById(componentId);
+        if (vertexResult.isLeft()){
+            return doAction(RESTORE, vertexResult.left().value());
+        } else {
+            return Either.right(onError(RESTORE.name(), componentId, vertexResult.right().value()));
+        }
+    }
+
+    public ActionStatus onVspRestored(String csarId){
+        return onVspStateChanged(RESTORE, csarId);
+    }
+
+    public ActionStatus onVspArchived(String csarId){
+        return onVspStateChanged(ARCHIVE, csarId);
+    }
+
+    private ActionStatus onVspStateChanged(Action action, String csarId) {
+        Map<GraphPropertyEnum, Object> props = new HashMap<>();
+        props.put(GraphPropertyEnum.CSAR_UUID, csarId);
+        Either<List<GraphVertex>, TitanOperationStatus> vfsE = titanDao.getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, props);
+        return vfsE.either(vList -> setVspArchived(action, vList), s -> onError("VSP_"+action.name(), csarId, s));
+    }
+
+    private ActionStatus setVspArchived(Action action, List<GraphVertex> vList) {
+        if (!vList.isEmpty()) {
+            //Find & Lock the highest version component
+            GraphVertex highestVersion = this.getHighestVersionFrom(vList.get(0));
+            StorageOperationStatus lockStatus = this.graphLockOperation.lockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
+            if (lockStatus != StorageOperationStatus.OK){
+                return onError(action.name(), highestVersion.getUniqueId(), TitanOperationStatus.ALREADY_LOCKED);
+            }
+
+            try {
+                //Set isVspArchived flag
+                for (GraphVertex v : vList) {
+                    boolean val = action == ARCHIVE ? true : false;
+                    v.setJsonMetadataField(JsonPresentationFields.IS_VSP_ARCHIVED, val);
+                    v.addMetadataProperty(GraphPropertyEnum.IS_VSP_ARCHIVED, val);
+                    titanDao.updateVertex(v);
+                }
+                return commitAndCheck("VSP_"+action.name(), vList.toString());
+            } finally {
+                this.graphLockOperation.unlockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
+            }
+
+        }
+        return ActionStatus.OK;
+    }
+
+    public List<String> setArchivedOriginsFlagInComponentInstances(GraphVertex compositionService) {
+        List<String> ciUidsWithArchivedOrigins = new LinkedList();
+        Either<List<GraphVertex>, TitanOperationStatus> instanceOfVerticesE = titanDao.getChildrenVertecies(compositionService, EdgeLabelEnum.INSTANCE_OF, JsonParseFlagEnum.NoParse);
+        Either<List<GraphVertex>, TitanOperationStatus> proxyOfVerticesE = titanDao.getChildrenVertecies(compositionService, EdgeLabelEnum.PROXY_OF, JsonParseFlagEnum.NoParse);
+
+        List<GraphVertex> all = new LinkedList<>();
+        if (instanceOfVerticesE.isLeft()){
+            all.addAll(instanceOfVerticesE.left().value());
+        }
+        if (proxyOfVerticesE.isLeft()){
+            all.addAll(proxyOfVerticesE.left().value());
+        }
+
+        List<GraphVertex> archivedOrigins = all.stream().filter(v -> Boolean.TRUE.equals(v.getMetadataProperty(GraphPropertyEnum.IS_ARCHIVED))).collect(Collectors.toList());
+        List<String> archivedOriginsUids = archivedOrigins.stream().map(GraphVertex::getUniqueId).collect(Collectors.toList());
+
+        Map<String, CompositionDataDefinition> compositionsJson = (Map<String, CompositionDataDefinition>) compositionService.getJson();
+
+        if (compositionsJson != null) {
+            CompositionDataDefinition composition = compositionsJson.get(JsonConstantKeysEnum.COMPOSITION.getValue());
+            if (composition != null) {
+
+                //Get all component instances from composition
+                Map<String, ComponentInstanceDataDefinition> componentInstances = composition.getComponentInstances();
+
+                //Extract component instances uids that has archived origins
+                ciUidsWithArchivedOrigins = componentInstances.
+                        values().
+                        stream().
+                        //filter CIs whose origins are marked as archived (componentUid is in archivedOriginsUids) the second condition handles the PROXY_OF case)
+                        filter(ci -> archivedOriginsUids.contains(ci.getComponentUid()) || archivedOriginsUids.contains(ci.getToscaPresentationValue(JsonPresentationFields.CI_SOURCE_MODEL_UID))).
+                        map(ComponentInstanceDataDefinition::getUniqueId).collect(Collectors.toList());
+
+                //set archived origins flag
+                componentInstances.
+                        values().
+                        stream().
+                        filter(ci -> archivedOriginsUids.contains(ci.getComponentUid()) || archivedOriginsUids.contains(ci.getToscaPresentationValue(JsonPresentationFields.CI_SOURCE_MODEL_UID))).
+                        forEach( ci -> ci.setOriginArchived(true));
+
+            }
+        }
+
+        return ciUidsWithArchivedOrigins;
+    }
+
+    private Either<List<String>, ActionStatus> doAction(Action action, GraphVertex componentVertex){
+
+        GraphVertex highestVersion = this.getHighestVersionFrom(componentVertex);
+
+        if (action.equals(ARCHIVE) && isInCheckoutState(highestVersion)) {
+            return Either.right(ActionStatus.INVALID_SERVICE_STATE);
+        }
+
+        //Lock the Highest Version
+        StorageOperationStatus lockStatus = this.graphLockOperation.lockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
+        if (lockStatus != StorageOperationStatus.OK){
+            return Either.right(onError(action.name(), componentVertex.getUniqueId(), TitanOperationStatus.ALREADY_LOCKED));
+        }
+
+        //Refetch latest version with full parsing
+        highestVersion = this.titanDao.getVertexById(highestVersion.getUniqueId(), JsonParseFlagEnum.ParseAll).left().value();
+
+        try {
+            //Get Catalog and Archive Roots
+            GraphVertex catalogRoot = titanDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT).left().value();
+            GraphVertex archiveRoot = titanDao.getVertexByLabel(VertexTypeEnum.ARCHIVE_ROOT).left().value();
+
+            if (action == ARCHIVE) {
+                archiveEdges(catalogRoot, archiveRoot, highestVersion);
+            } else if (action == RESTORE) {
+                restoreEdges(catalogRoot, archiveRoot, highestVersion);
+            }
+            setPropertiesByAction(highestVersion, action);
+            titanDao.updateVertex(highestVersion);
+
+            List<String> affectedComponentIds = handleParents(highestVersion, catalogRoot, archiveRoot, action);
+            ActionStatus sc = commitAndCheck(action.name(), highestVersion.getUniqueId());
+            return  sc == ActionStatus.OK ? Either.left(affectedComponentIds) : Either.right(sc);
+        } finally {
+            this.graphLockOperation.unlockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
+        }
+    }
+
+    private ActionStatus commitAndCheck(String action, String componentId) {
+        TitanOperationStatus status = titanDao.commit();
+        if (!status.equals(TitanOperationStatus.OK)){
+            return onError(action, componentId, status);
+        }
+        return ActionStatus.OK;
+    }
+
+    private boolean isInCheckoutState(GraphVertex v) {
+        if (LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name().equals(v.getMetadataProperty(GraphPropertyEnum.STATE))){
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Walks on children until highest version is reached
+     * @param v
+     * @return
+     */
+    private GraphVertex getHighestVersionFrom(GraphVertex v) {
+        Either<GraphVertex, TitanOperationStatus> childVertexE = titanDao.getChildVertex(v, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
+        GraphVertex highestVersionVertex = v;
+
+        while (childVertexE.isLeft()) {
+            highestVersionVertex = childVertexE.left().value();
+            childVertexE = titanDao.getChildVertex(highestVersionVertex, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
+        }
+        return highestVersionVertex;
+    }
+
+    private boolean isHighestVersion(GraphVertex v){
+        Boolean highest = (Boolean) v.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
+        return highest != null && highest;
+    }
+
+    private List<String> handleParents(GraphVertex v, GraphVertex catalogRoot, GraphVertex archiveRoot, Action action) {
+        Either<GraphVertex, TitanOperationStatus> parentVertexE = titanDao.getParentVertex(v, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll);
+        List<String> affectedCompIds = new ArrayList();
+        affectedCompIds.add(v.getUniqueId());
+
+        while (parentVertexE.isLeft()){
+            GraphVertex cv = parentVertexE.left().value();
+            affectedCompIds.add(cv.getUniqueId());
+            boolean isHighestVersion = isHighestVersion(cv);
+            if (isHighestVersion){
+                if (action == ARCHIVE) {
+                    archiveEdges(catalogRoot, archiveRoot, cv);
+                } else {
+                    restoreEdges(catalogRoot, archiveRoot, cv);
+                }
+            }
+            setPropertiesByAction(cv, action);
+            titanDao.updateVertex(cv);
+            parentVertexE = titanDao.getParentVertex(cv, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll);
+        }
+        return affectedCompIds;
+    }
+
+    private void archiveEdges(GraphVertex catalogRoot, GraphVertex archiveRoot, GraphVertex v) {
+        titanDao.deleteAllEdges(catalogRoot, v, EdgeLabelEnum.CATALOG_ELEMENT);
+        titanDao.createEdge(archiveRoot, v, EdgeLabelEnum.ARCHIVE_ELEMENT, null);
+        setPropertiesByAction(v, ARCHIVE);
+    }
+
+    private void restoreEdges(GraphVertex catalogRoot, GraphVertex archiveRoot, GraphVertex v) {
+        titanDao.deleteAllEdges(archiveRoot, v, EdgeLabelEnum.ARCHIVE_ELEMENT);
+        titanDao.createEdge(catalogRoot, v, EdgeLabelEnum.CATALOG_ELEMENT, null);
+        setPropertiesByAction(v, RESTORE);
+    }
+
+    private void setPropertiesByAction(GraphVertex v, Action action) {
+        long now = System.currentTimeMillis();
+
+        boolean isArchived = action == ARCHIVE ? true : false;
+        v.addMetadataProperty(GraphPropertyEnum.IS_ARCHIVED, isArchived);
+        v.addMetadataProperty(GraphPropertyEnum.ARCHIVE_TIME, now);
+        v.setJsonMetadataField(JsonPresentationFields.IS_ARCHIVED, isArchived);
+        v.setJsonMetadataField(JsonPresentationFields.ARCHIVE_TIME, now);
+    }
+
+    private ActionStatus onError(String action, String componentId, TitanOperationStatus s) {
+        ActionStatus ret = ActionStatus.GENERAL_ERROR;
+        if (s == TitanOperationStatus.NOT_FOUND){
+            ret = ActionStatus.RESOURCE_NOT_FOUND;
+        } else if (s == TitanOperationStatus.ALREADY_LOCKED) {
+            ret = ActionStatus.COMPONENT_IN_USE;
+        }
+        String retCodeVal = ret.name();
+        log.error("error occurred when trying to {} {}. Return code is: {}", action, componentId, retCodeVal);
+        return ret;
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperations.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperations.java
index 872a160..009d4ca 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperations.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperations.java
@@ -20,16 +20,7 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
+import fj.data.Either;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.tuple.ImmutableTriple;
 import org.apache.commons.lang3.tuple.Triple;
@@ -58,107 +49,109 @@
 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.slf4j.MDC;
 
-import fj.data.Either;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
 
 @org.springframework.stereotype.Component("artifacts-operations")
 
 public class ArtifactsOperations extends BaseOperation {
-	private static Logger log = LoggerFactory.getLogger(ArtifactsOperations.class.getName());
+    private static final String FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR = "failed to fetch {} for tosca element with id {}, error {}";
+	private static final Logger log = Logger.getLogger(ArtifactsOperations.class.getName());
 
-	public Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, String instanceId) {
+    public Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, String instanceId) {
 
-		String artifactId = artifactInfo.getUniqueId();
-		if (artifactId == null && artifactInfo.getEsId() != null) {
-			artifactId = artifactInfo.getEsId();
-		}
-		Either<ArtifactDataDefinition, StorageOperationStatus> status = updateArtifactOnGraph(parentId, artifactInfo, type, artifactId, instanceId, false, false);
-		if (status.isRight()) {
+        String artifactId = artifactInfo.getUniqueId();
+        if (artifactId == null && artifactInfo.getEsId() != null) {
+            artifactId = artifactInfo.getEsId();
+        }
+        Either<ArtifactDataDefinition, StorageOperationStatus> status = updateArtifactOnGraph(parentId, artifactInfo, type, artifactId, instanceId, false, false);
+        if (status.isRight()) {
 
-			log.debug("Failed to update artifact {} of {} {}. status is {}", artifactInfo.getArtifactName(), type.getName(), parentId, status.right().value());
-			BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactInfo.getArtifactName(), String.valueOf(status.right().value()));
-			return Either.right(status.right().value());
-		} else {
+            log.debug("Failed to update artifact {} of {} {}. status is {}", artifactInfo.getArtifactName(), type.getName(), parentId, status.right().value());
+            BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactInfo.getArtifactName(), String.valueOf(status.right().value()));
+            return Either.right(status.right().value());
+        } else {
 
-			ArtifactDataDefinition artifactData = status.left().value();
+            ArtifactDataDefinition artifactData = status.left().value();
 
-			ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactInfo, artifactData);
-			log.debug("The returned ArtifactDefintion is {}", artifactDefResult);
-			return Either.left(artifactDefResult);
-		}
+            ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactInfo, artifactData);
+            log.debug("The returned ArtifactDefintion is {}", artifactDefResult);
+            return Either.left(artifactDefResult);
+        }
 
-	}
+    }
 
-	public Either<ArtifactDefinition, StorageOperationStatus> updateArtifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, String instanceId) {
+    public Either<ArtifactDefinition, StorageOperationStatus> updateArtifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, String instanceId) {
 
-		Either<ArtifactDataDefinition, StorageOperationStatus> status = updateArtifactOnGraph(id, artifactInfo, type, artifactId, instanceId, true, false);
-		if (status.isRight()) {
+        Either<ArtifactDataDefinition, StorageOperationStatus> status = updateArtifactOnGraph(id, artifactInfo, type, artifactId, instanceId, true, false);
+        if (status.isRight()) {
 
-			log.debug("Failed to update artifact {} of {} {}. status is {}", artifactInfo.getArtifactName(), type.getName(), id, status.right().value());
-			BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactInfo.getArtifactName(), String.valueOf(status.right().value()));
-			return Either.right(status.right().value());
-		} else {
+            log.debug("Failed to update artifact {} of {} {}. status is {}", artifactInfo.getArtifactName(), type.getName(), id, status.right().value());
+            BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactInfo.getArtifactName(), String.valueOf(status.right().value()));
+            return Either.right(status.right().value());
+        } else {
 
-			ArtifactDataDefinition artifactData = status.left().value();
+            ArtifactDataDefinition artifactData = status.left().value();
 
-			ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactInfo, artifactData);
-			log.debug("The returned ArtifactDefintion is {}", artifactDefResult);
-			return Either.left(artifactDefResult);
-		}
-	}
+            ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactInfo, artifactData);
+            log.debug("The returned ArtifactDefintion is {}", artifactDefResult);
+            return Either.left(artifactDefResult);
+        }
+    }
 
-	public Either<Boolean, StorageOperationStatus> isCloneNeeded(String parentId, ArtifactDefinition artifactInfo, NodeTypeEnum type) {
-		ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
+    public Either<Boolean, StorageOperationStatus> isCloneNeeded(String parentId, ArtifactDefinition artifactInfo, NodeTypeEnum type) {
+        ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
 
-		Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, type);
-		EdgeLabelEnum edgeLabelEnum = triple.getLeft();
-		return super.isCloneNeeded(parentId, edgeLabelEnum);
-	}
+        Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, type);
+        EdgeLabelEnum edgeLabelEnum = triple.getLeft();
+        return super.isCloneNeeded(parentId, edgeLabelEnum);
+    }
 
-	public Either<ArtifactDefinition, StorageOperationStatus> getArtifactById(String parentId, String id) {
-		return getArtifactById(parentId, id, null, null);
-	}
+    public Either<ArtifactDefinition, StorageOperationStatus> getArtifactById(String parentId, String id) {
+        return getArtifactById(parentId, id, null, null);
+    }
 
-	public Either<ArtifactDefinition, StorageOperationStatus> getArtifactById(String parentId, String id, ComponentTypeEnum componentType, String containerId) {
-		Either<ArtifactDefinition, StorageOperationStatus> result = null;
-		ArtifactDataDefinition foundArtifact = null;
-		if (componentType != null && componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
-			foundArtifact = getInstanceArtifactByLabelAndId(parentId, id, containerId, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
-			if (foundArtifact == null) {
-				foundArtifact = getInstanceArtifactByLabelAndId(parentId, id, containerId, EdgeLabelEnum.INSTANCE_ARTIFACTS);
-			}
-		}
-		if (foundArtifact == null) {
-			foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
-		}
-		if (foundArtifact == null) {
-			foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.TOSCA_ARTIFACTS);
-		}
+    public Either<ArtifactDefinition, StorageOperationStatus> getArtifactById(String parentId, String id, ComponentTypeEnum componentType, String containerId) {
+        Either<ArtifactDefinition, StorageOperationStatus> result = null;
+        ArtifactDataDefinition foundArtifact = null;
+        if (componentType != null && componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
+            foundArtifact = getInstanceArtifactByLabelAndId(parentId, id, containerId, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
+            if (foundArtifact == null) {
+                foundArtifact = getInstanceArtifactByLabelAndId(parentId, id, containerId, EdgeLabelEnum.INSTANCE_ARTIFACTS);
+            }
+        }
+        if (foundArtifact == null) {
+            foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
+        }
+        if (foundArtifact == null) {
+            foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.TOSCA_ARTIFACTS);
+        }
 
-		if (foundArtifact == null) {
-			foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.ARTIFACTS);
-		}
+        if (foundArtifact == null) {
+            foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.ARTIFACTS);
+        }
 
-		if (foundArtifact == null) {
-			foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.SERVICE_API_ARTIFACTS);
-		}
+        if (foundArtifact == null) {
+            foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.SERVICE_API_ARTIFACTS);
+        }
 		if (foundArtifact == null) {
 			foundArtifact = findInterfaceArtifact(parentId, id);
 
 		}
 
-		if (foundArtifact == null) {
-			result = Either.right(StorageOperationStatus.NOT_FOUND);
-			return result;
-		}
+        if (foundArtifact == null) {
+            result = Either.right(StorageOperationStatus.NOT_FOUND);
+            return result;
+        }
 
-		ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(null, foundArtifact);
-		return Either.left(artifactDefResult);
+        ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(null, foundArtifact);
+        return Either.left(artifactDefResult);
 
-	}
+    }
 	private ArtifactDataDefinition findInterfaceArtifact(String parentId, String id) {
 		Either<Map<String, InterfaceDefinition>, TitanOperationStatus> dataFromGraph = getDataFromGraph(parentId, EdgeLabelEnum.INTERFACE_ARTIFACTS);
 		if (dataFromGraph.isRight()){
@@ -201,568 +194,565 @@
 	}
 
 
-	public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
-		Either<ArtifactDefinition, StorageOperationStatus> status = removeArtifactOnGraph(id, artifactId, type, deleteMandatoryArtifact);
+    public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
+        Either<ArtifactDefinition, StorageOperationStatus> status = removeArtifactOnGraph(id, artifactId, type, deleteMandatoryArtifact);
 
-		if (status.isRight()) {
+        if (status.isRight()) {
 
-			log.debug("Failed to delete artifact {} of resource {}", artifactId, id);
+            log.debug("Failed to delete artifact {} of resource {}", artifactId, id);
 
-			BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete Artifact", artifactId, String.valueOf(status.right().value()));
-			return Either.right(status.right().value());
-		} else {
+            BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete Artifact", artifactId, String.valueOf(status.right().value()));
+            return Either.right(status.right().value());
+        } else {
 
-			return Either.left(status.left().value());
-		}
-	}
+            return Either.left(status.left().value());
+        }
+    }
 
-	public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, ArtifactGroupTypeEnum groupType, String instanceId) {
+    public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, ArtifactGroupTypeEnum groupType, String instanceId) {
 
-		Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, parentType);
-		EdgeLabelEnum edgeLabelEnum = triple.getLeft();
+        Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, parentType);
+        EdgeLabelEnum edgeLabelEnum = triple.getLeft();
 
-		Either<Map<String, ArtifactDefinition>, TitanOperationStatus> foundArtifact = null;
-		Map<String, ArtifactDefinition> resMap = new HashMap<>();
-		foundArtifact = getArtifactByLabel(parentId, instanceId, edgeLabelEnum);
-		if (foundArtifact.isRight()) {
-			log.debug("Failed to find artifact in component {} with label {} ", parentId, edgeLabelEnum);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(foundArtifact.right().value()));
-		}
+        Either<Map<String, ArtifactDefinition>, TitanOperationStatus> foundArtifact = null;
+        Map<String, ArtifactDefinition> resMap = new HashMap<>();
+        foundArtifact = getArtifactByLabel(parentId, instanceId, edgeLabelEnum);
+        if (foundArtifact.isRight()) {
+            log.debug("Failed to find artifact in component {} with label {} ", parentId, edgeLabelEnum);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(foundArtifact.right().value()));
+        }
 
-		resMap.putAll(foundArtifact.left().value());
+        resMap.putAll(foundArtifact.left().value());
 
-		return Either.left(resMap);
-	}
+        return Either.left(resMap);
+    }
 
-	/**
-	 * @param parentId   the id of the instance container
-	 * @param instanceId the id of the instance of which to return its artifacts
-	 * @return instance and instance deployment artifacts mapped by artifact label name
-	 */
-	public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getAllInstanceArtifacts(String parentId, String instanceId) {
-		Map<String, ArtifactDataDefinition> resMap = new HashMap<>();
-		Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> instArtifacts = getInstanceArtifactsByLabel(parentId, instanceId, EdgeLabelEnum.INSTANCE_ARTIFACTS);
-		if (instArtifacts.isRight()) {
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(instArtifacts.right().value()));
-		}
-		Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> deployInstArtifacts = getInstanceArtifactsByLabel(parentId, instanceId, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
-		if (deployInstArtifacts.isRight()) {
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deployInstArtifacts.right().value()));
-		}
-		resMap.putAll(instArtifacts.left().value());
-		resMap.putAll(deployInstArtifacts.left().value());
-		return Either.left(convertArtifactMapToArtifactDefinitionMap(resMap));
-	}
+    /**
+     * @param parentId   the id of the instance container
+     * @param instanceId the id of the instance of which to return its artifacts
+     * @return instance and instance deployment artifacts mapped by artifact label name
+     */
+    public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getAllInstanceArtifacts(String parentId, String instanceId) {
+        Map<String, ArtifactDataDefinition> resMap = new HashMap<>();
+        Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> instArtifacts = getInstanceArtifactsByLabel(parentId, instanceId, EdgeLabelEnum.INSTANCE_ARTIFACTS);
+        if (instArtifacts.isRight()) {
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(instArtifacts.right().value()));
+        }
+        Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> deployInstArtifacts = getInstanceArtifactsByLabel(parentId, instanceId, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
+        if (deployInstArtifacts.isRight()) {
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deployInstArtifacts.right().value()));
+        }
+        resMap.putAll(instArtifacts.left().value());
+        resMap.putAll(deployInstArtifacts.left().value());
+        return Either.left(convertArtifactMapToArtifactDefinitionMap(resMap));
+    }
 
-	public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId) {
+    public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId) {
 
-		Either<Map<String, ArtifactDefinition>, TitanOperationStatus> foundArtifact = null;
-		Map<String, ArtifactDefinition> resMap = new HashMap<>();
-		foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.ARTIFACTS);
-		if (foundArtifact.isLeft()) {
-			resMap.putAll(foundArtifact.left().value());
+        Either<Map<String, ArtifactDefinition>, TitanOperationStatus> foundArtifact = null;
+        Map<String, ArtifactDefinition> resMap = new HashMap<>();
+        foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.ARTIFACTS);
+        if (foundArtifact.isLeft()) {
+            resMap.putAll(foundArtifact.left().value());
 
-		}
-		foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
-		if (foundArtifact.isLeft()) {
-			resMap.putAll(foundArtifact.left().value());
+        }
+        foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
+        if (foundArtifact.isLeft()) {
+            resMap.putAll(foundArtifact.left().value());
 
-		}
-		foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.TOSCA_ARTIFACTS);
-		if (foundArtifact.isLeft()) {
-			resMap.putAll(foundArtifact.left().value());
+        }
+        foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.TOSCA_ARTIFACTS);
+        if (foundArtifact.isLeft()) {
+            resMap.putAll(foundArtifact.left().value());
 
-		}
+        }
 
-		return Either.left(resMap);
+        return Either.left(resMap);
 
-	}
+    }
 
-	public Either<ArtifactDefinition, StorageOperationStatus> removeArtifactOnGraph(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
+    public Either<ArtifactDefinition, StorageOperationStatus> removeArtifactOnGraph(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
 
-		Either<ArtifactDefinition, StorageOperationStatus> artifactData = this.getArtifactById(id, artifactId);
-		if (artifactData.isRight()) {
-			log.debug("Failed to find artifact in component {} with id {} ", id, artifactId);
-			return Either.right(artifactData.right().value());
-		}
-		ArtifactDataDefinition artifactDefinition = artifactData.left().value();
-		boolean isMandatory = false;
-		if ((artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) && !deleteMandatoryArtifact) {
-			// return Either.left(artifactData.left().value());
-			isMandatory = true;
-		}
+        Either<ArtifactDefinition, StorageOperationStatus> artifactData = this.getArtifactById(id, artifactId);
+        if (artifactData.isRight()) {
+            log.debug("Failed to find artifact in component {} with id {} ", id, artifactId);
+            return Either.right(artifactData.right().value());
+        }
+        ArtifactDataDefinition artifactDefinition = artifactData.left().value();
+        boolean isMandatory = false;
+        if ((artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) && !deleteMandatoryArtifact) {
+            // return Either.left(artifactData.left().value());
+            isMandatory = true;
+        }
 
-		Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactDefinition.getArtifactGroupType(), type);
-		EdgeLabelEnum edgeLabelEnum = triple.getLeft();
-		VertexTypeEnum vertexTypeEnum = triple.getRight();
+        Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactDefinition.getArtifactGroupType(), type);
+        EdgeLabelEnum edgeLabelEnum = triple.getLeft();
+        VertexTypeEnum vertexTypeEnum = triple.getRight();
 
-		if (!isMandatory) {
-			StorageOperationStatus status = deleteToscaDataElement(id, edgeLabelEnum, vertexTypeEnum, artifactDefinition.getArtifactLabel(), JsonPresentationFields.ARTIFACT_LABEL);
-			if (status != StorageOperationStatus.OK)
-				return Either.right(status);
-		}
+        if (!isMandatory) {
+            StorageOperationStatus status = deleteToscaDataElement(id, edgeLabelEnum, vertexTypeEnum, artifactDefinition.getArtifactLabel(), JsonPresentationFields.ARTIFACT_LABEL);
+            if (status != StorageOperationStatus.OK)
+                return Either.right(status);
+        }
 
-		return Either.left(artifactData.left().value());
+        return Either.left(artifactData.left().value());
 
-	}
+    }
 
-	public void updateUUID(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion, boolean isUpdate, EdgeLabelEnum edgeLabel) {
-		if (oldVesrion == null || oldVesrion.isEmpty())
-			oldVesrion = "0";
+    public void updateUUID(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion, boolean isUpdate, EdgeLabelEnum edgeLabel) {
+        if (oldVesrion == null || oldVesrion.isEmpty())
+            oldVesrion = "0";
 
-		String currentChecksum = artifactData.getArtifactChecksum();
+        String currentChecksum = artifactData.getArtifactChecksum();
 
-		if (isUpdate) {
-			ArtifactTypeEnum type = ArtifactTypeEnum.findType(artifactData.getArtifactType());
-			switch (type) {
-				case HEAT_ENV:
-					if (edgeLabel == EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS) {
-						generateUUID(artifactData, oldVesrion);
-					} else {
-						updateVersionAndDate(artifactData, oldVesrion);
-					}
-					break;
-				case HEAT:
-				case HEAT_NET:
-				case HEAT_VOL:
-					generateUUID(artifactData, oldVesrion);
-					break;
-				default:
-					if (oldChecksum == null || oldChecksum.isEmpty()) {
-						if (currentChecksum != null) {
-							generateUUID(artifactData, oldVesrion);
-						}
-					} else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) {
-						generateUUID(artifactData, oldVesrion);
-					}
-					break;
-			}
-		} else {
-			if (oldChecksum == null || oldChecksum.isEmpty()) {
-				if (currentChecksum != null) {
-					generateUUID(artifactData, oldVesrion);
-				}
-			} else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) {
-				generateUUID(artifactData, oldVesrion);
-			}
-		}
-	}
+        if (isUpdate) {
+            ArtifactTypeEnum type = ArtifactTypeEnum.findType(artifactData.getArtifactType());
+            switch (type) {
+                case HEAT_ENV:
+                    if (edgeLabel == EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS) {
+                        generateUUID(artifactData, oldVesrion);
+                    } else {
+                        updateVersionAndDate(artifactData, oldVesrion);
+                    }
+                    break;
+                case HEAT:
+                case HEAT_NET:
+                case HEAT_VOL:
+                    generateUUID(artifactData, oldVesrion);
+                    break;
+                default:
+                    if (oldChecksum == null || oldChecksum.isEmpty()) {
+                        if (currentChecksum != null) {
+                            generateUUID(artifactData, oldVesrion);
+                        }
+                    } else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) {
+                        generateUUID(artifactData, oldVesrion);
+                    }
+                    break;
+            }
+        } else {
+            if (oldChecksum == null || oldChecksum.isEmpty()) {
+                if (currentChecksum != null) {
+                    generateUUID(artifactData, oldVesrion);
+                }
+            } else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) {
+                generateUUID(artifactData, oldVesrion);
+            }
+        }
+    }
 
-	// @TODO add implementation
+    // @TODO add implementation
 
-	public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType) {
-		return null;
-	}
+    public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType) {
+        return null;
+    }
 
-	public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifactHeat, String componentId, NodeTypeEnum parentType, boolean failIfExist, String instanceId) {
-		artifactHeatEnv.setGeneratedFromId(artifactHeat.getUniqueId());
-		return addArifactToComponent(artifactHeatEnv, componentId, parentType, failIfExist, instanceId);
-	}
+    public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifactHeat, String componentId, NodeTypeEnum parentType, boolean failIfExist, String instanceId) {
+        artifactHeatEnv.setGeneratedFromId(artifactHeat.getUniqueId());
+        return addArifactToComponent(artifactHeatEnv, componentId, parentType, failIfExist, instanceId);
+    }
 
-	public Either<ArtifactDefinition, StorageOperationStatus> getHeatArtifactByHeatEnvId(String parentId, ArtifactDefinition heatEnv, NodeTypeEnum parentType, String containerId, ComponentTypeEnum componentType) {
-		String id = heatEnv.getGeneratedFromId();
-		ComponentTypeEnum compType;
-		switch (parentType) {
-			case ResourceInstance:
-				compType = ComponentTypeEnum.RESOURCE_INSTANCE;
-				break;
-			default:
-				compType = componentType;
-		}
-		return getArtifactById(parentId, id, compType, containerId);
-	}
+    public Either<ArtifactDefinition, StorageOperationStatus> getHeatArtifactByHeatEnvId(String parentId, ArtifactDefinition heatEnv, NodeTypeEnum parentType, String containerId, ComponentTypeEnum componentType) {
+        String id = heatEnv.getGeneratedFromId();
+        ComponentTypeEnum compType;
+        switch (parentType) {
+            case ResourceInstance:
+                compType = ComponentTypeEnum.RESOURCE_INSTANCE;
+                break;
+            default:
+                compType = componentType;
+        }
+        return getArtifactById(parentId, id, compType, containerId);
+    }
 
-	public Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact(String id, ArtifactDefinition artifactEnvInfo, String artifactId, String newArtifactId, NodeTypeEnum type, String instanceId) {
+    public Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact(String id, ArtifactDefinition artifactEnvInfo, String artifactId, String newArtifactId, NodeTypeEnum type, String instanceId) {
 
-		Either<Map<String, ArtifactDefinition>, TitanOperationStatus> artifactsEither = getArtifactByLabel(id, instanceId, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
-		if (artifactsEither.isRight()) {
-			log.debug("Failed to find artifacts in component {} with id {} ", id, artifactsEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(artifactsEither.right().value()));
-		}
+        Either<Map<String, ArtifactDefinition>, TitanOperationStatus> artifactsEither = getArtifactByLabel(id, instanceId, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
+        if (artifactsEither.isRight()) {
+            log.debug("Failed to find artifacts in component {} with id {} ", id, artifactsEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(artifactsEither.right().value()));
+        }
 
-		Map<String, ArtifactDefinition> artifacts = artifactsEither.left().value();
-		List<ArtifactDefinition> envList = artifacts.values().stream().filter(a -> a.getGeneratedFromId() != null && a.getGeneratedFromId().equals(artifactId)).collect(Collectors.toList());
-		if (envList != null && !envList.isEmpty()) {
-			envList.forEach(a -> {
-				a.setGeneratedFromId(newArtifactId);
-				updateArtifactOnResource(a, id, a.getUniqueId(), type, instanceId);
+        Map<String, ArtifactDefinition> artifacts = artifactsEither.left().value();
+        List<ArtifactDefinition> envList = artifacts.values().stream().filter(a -> a.getGeneratedFromId() != null && a.getGeneratedFromId().equals(artifactId)).collect(Collectors.toList());
+        if (envList != null && !envList.isEmpty()) {
+            envList.forEach(a -> {
+                a.setGeneratedFromId(newArtifactId);
+                updateArtifactOnResource(a, id, a.getUniqueId(), type, instanceId);
 
-			});
+            });
 
-		}
-		return Either.left(artifactEnvInfo);
-	}
+        }
+        return Either.left(artifactEnvInfo);
+    }
 
-	public Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvPlaceholder(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type) {
+    public Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvPlaceholder(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type) {
 		return updateArtifactOnResource(artifactInfo, parentId, artifactInfo.getUniqueId(), type, null);
-	}
+    }
 
-	// public Either<List<HeatParameterDefinition>, StorageOperationStatus> getHeatParamsForEnv(ArtifactDefinition heatEnvArtifact, String parentId) {
-	// return null;
-	// }
 
-	///////////////////////////////////////////// private methods ////////////////////////////////////////////////////
+    ///////////////////////////////////////////// private methods ////////////////////////////////////////////////////
 
-	protected ArtifactDefinition convertArtifactDataToArtifactDefinition(ArtifactDefinition artifactInfo, ArtifactDataDefinition artifactDefResult) {
-		log.debug("The object returned after create property is {}", artifactDefResult);
+    protected ArtifactDefinition convertArtifactDataToArtifactDefinition(ArtifactDefinition artifactInfo, ArtifactDataDefinition artifactDefResult) {
+        log.debug("The object returned after create property is {}", artifactDefResult);
 
-		ArtifactDefinition propertyDefResult = new ArtifactDefinition(artifactDefResult);
-		if (artifactInfo != null)
-			propertyDefResult.setPayload(artifactInfo.getPayloadData());
+        ArtifactDefinition propertyDefResult = new ArtifactDefinition(artifactDefResult);
+        if (artifactInfo != null)
+            propertyDefResult.setPayload(artifactInfo.getPayloadData());
 
-		List<HeatParameterDefinition> parameters = new ArrayList<HeatParameterDefinition>();
-		/*
-		 * StorageOperationStatus heatParametersOfNode = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefResult.getUniqueId().toString(), parameters); if ((heatParametersOfNode.equals(StorageOperationStatus.OK))
-		 * && !parameters.isEmpty()) { propertyDefResult.setHeatParameters(parameters); }
-		 */
-		return propertyDefResult;
-	}
+        List<HeatParameterDefinition> parameters = new ArrayList<>();
+        /*
+         * StorageOperationStatus heatParametersOfNode = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefResult.getUniqueId().toString(), parameters); if ((heatParametersOfNode.equals(StorageOperationStatus.OK))
+         * && !parameters.isEmpty()) { propertyDefResult.setHeatParameters(parameters); }
+         */
+        return propertyDefResult;
+    }
 
-	private ArtifactDataDefinition getInstanceArtifactByLabelAndId(String parentId, String id, String containerId, EdgeLabelEnum edgeLabelEnum) {
-		ArtifactDataDefinition foundArtifact = null;
-		Either<Map<String, MapArtifactDataDefinition>, TitanOperationStatus> artifactsEither = getDataFromGraph(containerId, edgeLabelEnum);
-		if (artifactsEither.isRight()) {
-			log.debug("failed to fetch {} for tosca element with id {}, error {}", edgeLabelEnum, containerId, artifactsEither.right().value());
-			return null;
-		}
+    private ArtifactDataDefinition getInstanceArtifactByLabelAndId(String parentId, String id, String containerId, EdgeLabelEnum edgeLabelEnum) {
+        ArtifactDataDefinition foundArtifact = null;
+        Either<Map<String, MapArtifactDataDefinition>, TitanOperationStatus> artifactsEither = getDataFromGraph(containerId, edgeLabelEnum);
+        if (artifactsEither.isRight()) {
+            log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, containerId, artifactsEither.right().value());
+            return null;
+        }
 
-		Map<String, MapArtifactDataDefinition> artifacts = artifactsEither.left().value();
+        Map<String, MapArtifactDataDefinition> artifacts = artifactsEither.left().value();
 
-		MapArtifactDataDefinition artifactsPerInstance = artifacts.get(parentId);
-		if (artifactsPerInstance == null) {
-			log.debug("failed to fetch artifacts for instance {} in tosca element with id {}, error {}", parentId, containerId, artifactsEither.right().value());
-			return null;
-		}
-		Optional<ArtifactDataDefinition> op = artifactsPerInstance.getMapToscaDataDefinition().values().stream().filter(p -> p.getUniqueId().equals(id)).findAny();
-		if (op.isPresent()) {
-			foundArtifact = op.get();
-		}
-		return foundArtifact;
-	}
+        MapArtifactDataDefinition artifactsPerInstance = artifacts.get(parentId);
+        if (artifactsPerInstance == null) {
+            log.debug("failed to fetch artifacts for instance {} in tosca element with id {}, error {}", parentId, containerId, artifactsEither.right().value());
+            return null;
+        }
+        Optional<ArtifactDataDefinition> op = artifactsPerInstance.getMapToscaDataDefinition().values().stream().filter(p -> p.getUniqueId().equals(id)).findAny();
+        if (op.isPresent()) {
+            foundArtifact = op.get();
+        }
+        return foundArtifact;
+    }
 
-	private ArtifactDataDefinition getArtifactByLabelAndId(String parentId, String id, EdgeLabelEnum edgeLabelEnum) {
-		ArtifactDataDefinition foundArtifact = null;
-		Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> artifactsEither = getDataFromGraph(parentId, edgeLabelEnum);
-		if (artifactsEither.isRight()) {
-			log.debug("failed to fetch {} for tosca element with id {}, error {}", edgeLabelEnum, parentId, artifactsEither.right().value());
-			return null;
-		}
+    private ArtifactDataDefinition getArtifactByLabelAndId(String parentId, String id, EdgeLabelEnum edgeLabelEnum) {
+        ArtifactDataDefinition foundArtifact = null;
+        Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> artifactsEither = getDataFromGraph(parentId, edgeLabelEnum);
+        if (artifactsEither.isRight()) {
+            log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, parentId, artifactsEither.right().value());
+            return null;
+        }
 
-		Map<String, ArtifactDataDefinition> artifacts = artifactsEither.left().value();
-		Optional<ArtifactDataDefinition> op = artifacts.values().stream().filter(p -> p.getUniqueId().equals(id)).findAny();
-		if (op.isPresent()) {
-			foundArtifact = op.get();
-		}
-		return foundArtifact;
-	}
+        Map<String, ArtifactDataDefinition> artifacts = artifactsEither.left().value();
+        Optional<ArtifactDataDefinition> op = artifacts.values().stream().filter(p -> p.getUniqueId().equals(id)).findAny();
+        if (op.isPresent()) {
+            foundArtifact = op.get();
+        }
+        return foundArtifact;
+    }
 
-	private Either<Map<String, ArtifactDefinition>, TitanOperationStatus> getArtifactByLabel(String parentId, String instanceId, EdgeLabelEnum edgeLabelEnum) {
-		Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> artifactsEither = getArtifactsDataByLabel(parentId, instanceId, edgeLabelEnum);
-		if (artifactsEither.isRight()) {
-			log.debug("failed to fetch {} for tosca element with id {}, error {}", edgeLabelEnum, parentId, artifactsEither.right().value());
-			return Either.right(artifactsEither.right().value());
-		}
-		Map<String, ArtifactDataDefinition> artifactDataMap = artifactsEither.left().value();
-		return Either.left(convertArtifactMapToArtifactDefinitionMap(artifactDataMap));
-	}
+    private Either<Map<String, ArtifactDefinition>, TitanOperationStatus> getArtifactByLabel(String parentId, String instanceId, EdgeLabelEnum edgeLabelEnum) {
+        Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> artifactsEither = getArtifactsDataByLabel(parentId, instanceId, edgeLabelEnum);
+        if (artifactsEither.isRight()) {
+            log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, parentId, artifactsEither.right().value());
+            return Either.right(artifactsEither.right().value());
+        }
+        Map<String, ArtifactDataDefinition> artifactDataMap = artifactsEither.left().value();
+        return Either.left(convertArtifactMapToArtifactDefinitionMap(artifactDataMap));
+    }
 
-	private Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> getArtifactsDataByLabel(String parentId, String instanceId, EdgeLabelEnum edgeLabelEnum) {
-		return edgeLabelEnum.isInstanceArtifactsLabel() ? getInstanceArtifactsByLabel(parentId, instanceId, edgeLabelEnum) : getDataFromGraph(parentId, edgeLabelEnum);
-	}
+    private Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> getArtifactsDataByLabel(String parentId, String instanceId, EdgeLabelEnum edgeLabelEnum) {
+        return edgeLabelEnum.isInstanceArtifactsLabel() ? getInstanceArtifactsByLabel(parentId, instanceId, edgeLabelEnum) : getDataFromGraph(parentId, edgeLabelEnum);
+    }
 
-	private Map<String, ArtifactDefinition> convertArtifactMapToArtifactDefinitionMap(Map<String, ArtifactDataDefinition> artifactDataMap) {
-		Map<String, ArtifactDefinition> artMap = new HashMap<>();
-		if (artifactDataMap != null && !artifactDataMap.isEmpty()) {
-			artMap = artifactDataMap.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e -> convertArtifactDataToArtifactDefinition(null, e.getValue())));
-		}
-		return artMap;
-	}
+    private Map<String, ArtifactDefinition> convertArtifactMapToArtifactDefinitionMap(Map<String, ArtifactDataDefinition> artifactDataMap) {
+        Map<String, ArtifactDefinition> artMap = new HashMap<>();
+        if (artifactDataMap != null && !artifactDataMap.isEmpty()) {
+            artMap = artifactDataMap.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e -> convertArtifactDataToArtifactDefinition(null, e.getValue())));
+        }
+        return artMap;
+    }
 
-	private Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> getInstanceArtifactsByLabel(String parentId, String instanceId, EdgeLabelEnum edgeLabelEnum) {
-		Either<Map<String, MapArtifactDataDefinition>, TitanOperationStatus> resultEither = getDataFromGraph(parentId, edgeLabelEnum);
-		if (resultEither.isRight()) {
-			log.debug("failed to fetch {} for tosca element with id {}, error {}", edgeLabelEnum, parentId, resultEither.right().value());
-			return Either.right(resultEither.right().value());
-		}
-		Map<String, MapArtifactDataDefinition> mapArtifacts = resultEither.left().value();
-		MapArtifactDataDefinition artifactPerInstance = mapArtifacts.get(instanceId);
-		return artifactPerInstance != null ? Either.left(artifactPerInstance.getMapToscaDataDefinition()) : Either.left(new HashMap<>());
-	}
+    private Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> getInstanceArtifactsByLabel(String parentId, String instanceId, EdgeLabelEnum edgeLabelEnum) {
+        Either<Map<String, MapArtifactDataDefinition>, TitanOperationStatus> resultEither = getDataFromGraph(parentId, edgeLabelEnum);
+        if (resultEither.isRight()) {
+            log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, parentId, resultEither.right().value());
+            return Either.right(resultEither.right().value());
+        }
+        Map<String, MapArtifactDataDefinition> mapArtifacts = resultEither.left().value();
+        MapArtifactDataDefinition artifactPerInstance = mapArtifacts.get(instanceId);
+        return artifactPerInstance != null ? Either.left(artifactPerInstance.getMapToscaDataDefinition()) : Either.left(new HashMap<>());
+    }
 
-	private Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> getEdgeLabelEnumFromArtifactGroupType(ArtifactGroupTypeEnum groupType, NodeTypeEnum nodeType) {
-		EdgeLabelEnum edgeLabelEnum;
-		VertexTypeEnum vertexTypeEnum;
-		Boolean isDeepElement = false;
-		/*
-		 * if (nodeType == NodeTypeEnum.ResourceInstance) { edgeLabelEnum = EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS; vertexTypeEnum = VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS; isDeepElement = true; } else {
-		 */
-		switch (groupType) {
-			case TOSCA:
-				edgeLabelEnum = EdgeLabelEnum.TOSCA_ARTIFACTS;
-				vertexTypeEnum = VertexTypeEnum.TOSCA_ARTIFACTS;
-				break;
-			case DEPLOYMENT:
-				if (nodeType == NodeTypeEnum.ResourceInstance) {
-					edgeLabelEnum = EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS;
-					vertexTypeEnum = VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS;
-					isDeepElement = true;
-				} else {
-					edgeLabelEnum = EdgeLabelEnum.DEPLOYMENT_ARTIFACTS;
-					vertexTypeEnum = VertexTypeEnum.DEPLOYMENT_ARTIFACTS;
-				}
-				break;
-			case SERVICE_API:
-				edgeLabelEnum = EdgeLabelEnum.SERVICE_API_ARTIFACTS;
-				vertexTypeEnum = VertexTypeEnum.SERVICE_API_ARTIFACTS;
-				break;
-			default:
-				if (nodeType == NodeTypeEnum.ResourceInstance) {
-					edgeLabelEnum = EdgeLabelEnum.INSTANCE_ARTIFACTS;
-					vertexTypeEnum = VertexTypeEnum.INSTANCE_ARTIFACTS;
-					isDeepElement = true;
-				} else {
-					edgeLabelEnum = EdgeLabelEnum.ARTIFACTS;
-					vertexTypeEnum = VertexTypeEnum.ARTIFACTS;
-				}
-				break;
-		}
-		// }
-		return new ImmutableTriple<EdgeLabelEnum, Boolean, VertexTypeEnum>(edgeLabelEnum, isDeepElement, vertexTypeEnum);
+    private Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> getEdgeLabelEnumFromArtifactGroupType(ArtifactGroupTypeEnum groupType, NodeTypeEnum nodeType) {
+        EdgeLabelEnum edgeLabelEnum;
+        VertexTypeEnum vertexTypeEnum;
+        Boolean isDeepElement = false;
+        /*
+         * if (nodeType == NodeTypeEnum.ResourceInstance) { edgeLabelEnum = EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS; vertexTypeEnum = VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS; isDeepElement = true; } else {
+         */
+        switch (groupType) {
+            case TOSCA:
+                edgeLabelEnum = EdgeLabelEnum.TOSCA_ARTIFACTS;
+                vertexTypeEnum = VertexTypeEnum.TOSCA_ARTIFACTS;
+                break;
+            case DEPLOYMENT:
+                if (nodeType == NodeTypeEnum.ResourceInstance) {
+                    edgeLabelEnum = EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS;
+                    vertexTypeEnum = VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS;
+                    isDeepElement = true;
+                } else {
+                    edgeLabelEnum = EdgeLabelEnum.DEPLOYMENT_ARTIFACTS;
+                    vertexTypeEnum = VertexTypeEnum.DEPLOYMENT_ARTIFACTS;
+                }
+                break;
+            case SERVICE_API:
+                edgeLabelEnum = EdgeLabelEnum.SERVICE_API_ARTIFACTS;
+                vertexTypeEnum = VertexTypeEnum.SERVICE_API_ARTIFACTS;
+                break;
+            default:
+                if (nodeType == NodeTypeEnum.ResourceInstance) {
+                    edgeLabelEnum = EdgeLabelEnum.INSTANCE_ARTIFACTS;
+                    vertexTypeEnum = VertexTypeEnum.INSTANCE_ARTIFACTS;
+                    isDeepElement = true;
+                } else {
+                    edgeLabelEnum = EdgeLabelEnum.ARTIFACTS;
+                    vertexTypeEnum = VertexTypeEnum.ARTIFACTS;
+                }
+                break;
+        }
+        // }
+        return new ImmutableTriple<>(edgeLabelEnum, isDeepElement, vertexTypeEnum);
 
-	}
+    }
 
-	public Either<ArtifactDataDefinition, StorageOperationStatus> updateArtifactOnGraph(String componentId, ArtifactDefinition artifactInfo, NodeTypeEnum type, String artifactId, String instanceId, boolean isUpdate, boolean isDeletePlaceholder) {
-		Either<ArtifactDataDefinition, StorageOperationStatus> res = null;
-		ArtifactDataDefinition artifactToUpdate = new ArtifactDataDefinition(artifactInfo);
-		ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
+    public Either<ArtifactDataDefinition, StorageOperationStatus> updateArtifactOnGraph(String componentId, ArtifactDefinition artifactInfo, NodeTypeEnum type, String artifactId, String instanceId, boolean isUpdate, boolean isDeletePlaceholder) {
+        Either<ArtifactDataDefinition, StorageOperationStatus> res = null;
+        ArtifactDataDefinition artifactToUpdate = new ArtifactDataDefinition(artifactInfo);
+        ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
 
-		Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, type);
-		EdgeLabelEnum edgeLabelEnum = triple.getLeft();
-		VertexTypeEnum vertexTypeEnum = triple.getRight();
+        Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, type);
+        EdgeLabelEnum edgeLabelEnum = triple.getLeft();
+        VertexTypeEnum vertexTypeEnum = triple.getRight();
 
-		Either<Boolean, StorageOperationStatus> isNeedToCloneEither = isCloneNeeded(componentId, edgeLabelEnum);
-		if (isNeedToCloneEither.isRight()) {
-			log.debug("Failed check is clone needed {}", componentId);
-			return Either.right(isNeedToCloneEither.right().value());
+        Either<Boolean, StorageOperationStatus> isNeedToCloneEither = isCloneNeeded(componentId, edgeLabelEnum);
+        if (isNeedToCloneEither.isRight()) {
+            log.debug("Failed check is clone needed {}", componentId);
+            return Either.right(isNeedToCloneEither.right().value());
 
-		}
-		boolean isNeedToClone = isNeedToCloneEither.left().value();
+        }
+        boolean isNeedToClone = isNeedToCloneEither.left().value();
 
-		if (artifactId == null || isNeedToClone) {
-			String uniqueId;
-			if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
-				uniqueId = UniqueIdBuilder.buildPropertyUniqueId(componentId, artifactToUpdate.getArtifactLabel());
-			} else {
-				uniqueId = UniqueIdBuilder.buildInstanceArtifactUniqueId(componentId, instanceId, artifactToUpdate.getArtifactLabel());
-			}
-			artifactToUpdate.setUniqueId(uniqueId);
-			if (!isDeletePlaceholder)
-				artifactToUpdate.setEsId(uniqueId);
-		} else
-			artifactToUpdate.setUniqueId(artifactId);
+        if (artifactId == null || isNeedToClone) {
+            String uniqueId;
+            if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
+                uniqueId = UniqueIdBuilder.buildPropertyUniqueId(componentId, artifactToUpdate.getArtifactLabel());
+            } else {
+                uniqueId = UniqueIdBuilder.buildInstanceArtifactUniqueId(componentId, instanceId, artifactToUpdate.getArtifactLabel());
+            }
+            artifactToUpdate.setUniqueId(uniqueId);
+            if (!isDeletePlaceholder)
+                artifactToUpdate.setEsId(uniqueId);
+        } else
+            artifactToUpdate.setUniqueId(artifactId);
 
-		Map<String, ArtifactDataDefinition> artifacts = new HashMap<>();
-		Map<String, MapArtifactDataDefinition> artifactInst = null;
-		if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
+        Map<String, ArtifactDataDefinition> artifacts = new HashMap<>();
+        Map<String, MapArtifactDataDefinition> artifactInst = null;
+        if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
 
-			Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> artifactsEither = this.getDataFromGraph(componentId, edgeLabelEnum);
+            Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> artifactsEither = this.getDataFromGraph(componentId, edgeLabelEnum);
 
-			if (artifactsEither.isLeft() && artifactsEither.left().value() != null && !artifactsEither.left().value().isEmpty()) {
-				artifacts = artifactsEither.left().value();
-				if (isNeedToClone && artifacts != null) {
-					artifacts.values().stream().forEach(a -> a.setDuplicated(Boolean.TRUE));
-				}
-			}
-		} else {
+            if (artifactsEither.isLeft() && artifactsEither.left().value() != null && !artifactsEither.left().value().isEmpty()) {
+                artifacts = artifactsEither.left().value();
+                if (isNeedToClone && artifacts != null) {
+                    artifacts.values().stream().forEach(a -> a.setDuplicated(Boolean.TRUE));
+                }
+            }
+        } else {
 
-			Either<Map<String, MapArtifactDataDefinition>, TitanOperationStatus> artifactsEither = this.getDataFromGraph(componentId, edgeLabelEnum);
-			if (artifactsEither.isLeft()) {
-				artifactInst = artifactsEither.left().value();
-				if (isNeedToClone && artifactInst != null) {
-					artifactInst.values().forEach(ma -> ma.getMapToscaDataDefinition().values().forEach(a -> a.setDuplicated(Boolean.TRUE)));
-				}
-				MapArtifactDataDefinition artifatcsOnInstance = artifactInst.get(instanceId);
-				if (artifatcsOnInstance != null) {
-					artifacts = artifatcsOnInstance.getMapToscaDataDefinition();
-				}
-			}
-		}
-		String oldChecksum = null;
-		String oldVersion = null;
-		if (artifacts != null && artifacts.containsKey(artifactInfo.getArtifactLabel())) {
-			ArtifactDataDefinition oldArtifactData = artifacts.get(artifactInfo.getArtifactLabel());
-			oldChecksum = oldArtifactData.getArtifactChecksum();
-			oldVersion = oldArtifactData.getArtifactVersion();
-			//duplicated flag didn't receive from UI, take from DB 
-			artifactToUpdate.setDuplicated(oldArtifactData.getDuplicated());
+            Either<Map<String, MapArtifactDataDefinition>, TitanOperationStatus> artifactsEither = this.getDataFromGraph(componentId, edgeLabelEnum);
+            if (artifactsEither.isLeft()) {
+                artifactInst = artifactsEither.left().value();
+                if (isNeedToClone && artifactInst != null) {
+                    artifactInst.values().forEach(ma -> ma.getMapToscaDataDefinition().values().forEach(a -> a.setDuplicated(Boolean.TRUE)));
+                }
+                MapArtifactDataDefinition artifatcsOnInstance = artifactInst.get(instanceId);
+                if (artifatcsOnInstance != null) {
+                    artifacts = artifatcsOnInstance.getMapToscaDataDefinition();
+                }
+            }
+        }
+        String oldChecksum = null;
+        String oldVersion = null;
+        if (artifacts != null && artifacts.containsKey(artifactInfo.getArtifactLabel())) {
+            ArtifactDataDefinition oldArtifactData = artifacts.get(artifactInfo.getArtifactLabel());
+            oldChecksum = oldArtifactData.getArtifactChecksum();
+            oldVersion = oldArtifactData.getArtifactVersion();
+            //duplicated flag didn't receive from UI, take from DB
+            artifactToUpdate.setDuplicated(oldArtifactData.getDuplicated());
 
-			if (isNeedToClone)
-				artifactToUpdate.setDuplicated(Boolean.FALSE);
-			else {
-				if (artifactToUpdate.getDuplicated()) {
-					String uniqueId = "";
-					if(type != NodeTypeEnum.ResourceInstance)
-						uniqueId = UniqueIdBuilder.buildPropertyUniqueId(componentId, artifactToUpdate.getArtifactLabel());
-					else
-						uniqueId = UniqueIdBuilder.buildInstanceArtifactUniqueId(componentId, instanceId, artifactToUpdate.getArtifactLabel());
-					
-					artifactToUpdate.setUniqueId(uniqueId);
-					if (!isDeletePlaceholder)
-						artifactToUpdate.setEsId(uniqueId);
-					artifactToUpdate.setDuplicated(Boolean.FALSE);
-				}
-			}
-		}
-		updateUUID(artifactToUpdate, oldChecksum, oldVersion, isUpdate, edgeLabelEnum);
+            if (isNeedToClone)
+                artifactToUpdate.setDuplicated(Boolean.FALSE);
+            else {
+                if (artifactToUpdate.getDuplicated()) {
+                    String uniqueId = "";
+                    if(type != NodeTypeEnum.ResourceInstance)
+                        uniqueId = UniqueIdBuilder.buildPropertyUniqueId(componentId, artifactToUpdate.getArtifactLabel());
+                    else
+                        uniqueId = UniqueIdBuilder.buildInstanceArtifactUniqueId(componentId, instanceId, artifactToUpdate.getArtifactLabel());
 
-		if (artifactInfo.getPayloadData() == null) {
-			if (!artifactToUpdate.getMandatory() || artifactToUpdate.getEsId() != null) {
-				artifactToUpdate.setEsId(artifactToUpdate.getUniqueId());
-			}
-		} else {
-			if (artifactToUpdate.getEsId() == null) {
-				artifactToUpdate.setEsId(artifactToUpdate.getUniqueId());
-			}
-		}
+                    artifactToUpdate.setUniqueId(uniqueId);
+                    if (!isDeletePlaceholder)
+                        artifactToUpdate.setEsId(uniqueId);
+                    artifactToUpdate.setDuplicated(Boolean.FALSE);
+                }
+            }
+        }
+        updateUUID(artifactToUpdate, oldChecksum, oldVersion, isUpdate, edgeLabelEnum);
 
-		StorageOperationStatus status = StorageOperationStatus.OK;
-		if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
-			List<ArtifactDataDefinition> toscaDataList = new ArrayList<>();
-			toscaDataList.add(artifactToUpdate);
+        if (artifactInfo.getPayloadData() == null) {
+            if (!artifactToUpdate.getMandatory() || artifactToUpdate.getEsId() != null) {
+                artifactToUpdate.setEsId(artifactToUpdate.getUniqueId());
+            }
+        } else {
+            if (artifactToUpdate.getEsId() == null) {
+                artifactToUpdate.setEsId(artifactToUpdate.getUniqueId());
+            }
+        }
 
-			if (isNeedToClone && artifacts != null) {
-				artifacts.values().stream().filter(a -> !a.getArtifactLabel().equals(artifactToUpdate.getArtifactLabel())).forEach(a -> toscaDataList.add(a));
-			}
-			status = updateToscaDataOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataList, JsonPresentationFields.ARTIFACT_LABEL);
-		} else {
-			List<ArtifactDataDefinition> toscaDataList = new ArrayList<>();
-			toscaDataList.add(artifactToUpdate);
-			List<String> pathKeys = new ArrayList<>();
-			pathKeys.add(instanceId);
-			if (isNeedToClone) {
-				MapArtifactDataDefinition artifatcsOnInstance = artifactInst.get(instanceId);
-				if (artifatcsOnInstance != null) {
-					artifacts = artifatcsOnInstance.getMapToscaDataDefinition();
-					artifacts.put(artifactToUpdate.getArtifactLabel(), artifactToUpdate);
-				}
+        StorageOperationStatus status = StorageOperationStatus.OK;
+        if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
+            List<ArtifactDataDefinition> toscaDataList = new ArrayList<>();
+            toscaDataList.add(artifactToUpdate);
 
-				for (Entry<String, MapArtifactDataDefinition> e : artifactInst.entrySet()) {
-					List<ArtifactDataDefinition> toscaDataListPerInst = e.getValue().getMapToscaDataDefinition().values().stream().collect(Collectors.toList());
-					List<String> pathKeysPerInst = new ArrayList<>();
-					pathKeysPerInst.add(e.getKey());
-					status = updateToscaDataDeepElementsOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataListPerInst, pathKeysPerInst, JsonPresentationFields.ARTIFACT_LABEL);
-					if (status != StorageOperationStatus.OK) {
-						log.debug("Failed to update atifacts group for instance {} in component {} edge type {} error {}", instanceId, componentId, edgeLabelEnum, status);
-						res = Either.right(status);
-						break;
-					}
-				}
-			} else {
-				status = updateToscaDataDeepElementsOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataList, pathKeys, JsonPresentationFields.ARTIFACT_LABEL);
-			}
-		}
-		if (status == StorageOperationStatus.OK)
-			res = Either.left(artifactToUpdate);
-		else
-			res = Either.right(status);
-		return res;
-	}
+            if (isNeedToClone && artifacts != null) {
+                artifacts.values().stream().filter(a -> !a.getArtifactLabel().equals(artifactToUpdate.getArtifactLabel())).forEach(toscaDataList::add);
+            }
+            status = updateToscaDataOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataList, JsonPresentationFields.ARTIFACT_LABEL);
+        } else {
+            List<ArtifactDataDefinition> toscaDataList = new ArrayList<>();
+            toscaDataList.add(artifactToUpdate);
+            List<String> pathKeys = new ArrayList<>();
+            pathKeys.add(instanceId);
+            if (isNeedToClone) {
+                MapArtifactDataDefinition artifatcsOnInstance = artifactInst.get(instanceId);
+                if (artifatcsOnInstance != null) {
+                    artifacts = artifatcsOnInstance.getMapToscaDataDefinition();
+                    artifacts.put(artifactToUpdate.getArtifactLabel(), artifactToUpdate);
+                }
 
-	public void generateUUID(ArtifactDataDefinition artifactData, String oldVesrion) {
+                for (Entry<String, MapArtifactDataDefinition> e : artifactInst.entrySet()) {
+                    List<ArtifactDataDefinition> toscaDataListPerInst = e.getValue().getMapToscaDataDefinition().values().stream().collect(Collectors.toList());
+                    List<String> pathKeysPerInst = new ArrayList<>();
+                    pathKeysPerInst.add(e.getKey());
+                    status = updateToscaDataDeepElementsOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataListPerInst, pathKeysPerInst, JsonPresentationFields.ARTIFACT_LABEL);
+                    if (status != StorageOperationStatus.OK) {
+                        log.debug("Failed to update atifacts group for instance {} in component {} edge type {} error {}", instanceId, componentId, edgeLabelEnum, status);
+                        res = Either.right(status);
+                        break;
+                    }
+                }
+            } else {
+                status = updateToscaDataDeepElementsOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataList, pathKeys, JsonPresentationFields.ARTIFACT_LABEL);
+            }
+        }
+        if (status == StorageOperationStatus.OK)
+            res = Either.left(artifactToUpdate);
+        else
+            res = Either.right(status);
+        return res;
+    }
 
-		UUID uuid = UUID.randomUUID();
-		artifactData.setArtifactUUID(uuid.toString());
-		MDC.put("serviceInstanceID", uuid.toString());
-		updateVersionAndDate(artifactData, oldVesrion);
-	}
+    public void generateUUID(ArtifactDataDefinition artifactData, String oldVesrion) {
 
-	private void updateVersionAndDate(ArtifactDataDefinition artifactData, String oldVesrion) {
-		if (artifactData.getArtifactChecksum() != null) {
-			long time = System.currentTimeMillis();
-			artifactData.setPayloadUpdateDate(time);
-		}
-		int newVersion = new Integer(oldVesrion).intValue();
-		newVersion++;
-		artifactData.setArtifactVersion(String.valueOf(newVersion));
-	}
+        UUID uuid = UUID.randomUUID();
+        artifactData.setArtifactUUID(uuid.toString());
+        MDC.put("serviceInstanceID", uuid.toString());
+        updateVersionAndDate(artifactData, oldVesrion);
+    }
 
-	public Either<ArtifactDataDefinition, StorageOperationStatus> removeArtifactOnGraph(ArtifactDefinition artifactFromGraph, String componentId, String instanceId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
+    private void updateVersionAndDate(ArtifactDataDefinition artifactData, String oldVesrion) {
+        if (artifactData.getArtifactChecksum() != null) {
+            long time = System.currentTimeMillis();
+            artifactData.setPayloadUpdateDate(time);
+        }
+        int newVersion = new Integer(oldVesrion).intValue();
+        newVersion++;
+        artifactData.setArtifactVersion(String.valueOf(newVersion));
+    }
 
-		Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactFromGraph.getArtifactGroupType(), type);
-		EdgeLabelEnum edgeLabelEnum = triple.getLeft();
-		VertexTypeEnum vertexTypeEnum = triple.getRight();
+    public Either<ArtifactDataDefinition, StorageOperationStatus> removeArtifactOnGraph(ArtifactDefinition artifactFromGraph, String componentId, String instanceId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
 
-		if (deleteMandatoryArtifact || !(artifactFromGraph.getMandatory() || artifactFromGraph.getServiceApi())) {
-			StorageOperationStatus status;
-			if (triple.getMiddle()) {
-				List<String> pathKeys = new ArrayList<>();
-				pathKeys.add(instanceId);
-				status = deleteToscaDataDeepElement(componentId, edgeLabelEnum, vertexTypeEnum, artifactFromGraph.getArtifactLabel(), pathKeys, JsonPresentationFields.ARTIFACT_LABEL);
-			} else {
-				status = deleteToscaDataElement(componentId, edgeLabelEnum, vertexTypeEnum, artifactFromGraph.getArtifactLabel(), JsonPresentationFields.ARTIFACT_LABEL);
-			}
-			if (status != StorageOperationStatus.OK)
-				return Either.right(status);
-		}
-		return Either.left(artifactFromGraph);
+        Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactFromGraph.getArtifactGroupType(), type);
+        EdgeLabelEnum edgeLabelEnum = triple.getLeft();
+        VertexTypeEnum vertexTypeEnum = triple.getRight();
 
-	}
+        if (deleteMandatoryArtifact || !(artifactFromGraph.getMandatory() || artifactFromGraph.getServiceApi())) {
+            StorageOperationStatus status;
+            if (triple.getMiddle()) {
+                List<String> pathKeys = new ArrayList<>();
+                pathKeys.add(instanceId);
+                status = deleteToscaDataDeepElement(componentId, edgeLabelEnum, vertexTypeEnum, artifactFromGraph.getArtifactLabel(), pathKeys, JsonPresentationFields.ARTIFACT_LABEL);
+            } else {
+                status = deleteToscaDataElement(componentId, edgeLabelEnum, vertexTypeEnum, artifactFromGraph.getArtifactLabel(), JsonPresentationFields.ARTIFACT_LABEL);
+            }
+            if (status != StorageOperationStatus.OK)
+                return Either.right(status);
+        }
+        return Either.left(artifactFromGraph);
 
-	public Either<ArtifactDataDefinition, StorageOperationStatus> deleteArtifactWithClonnigOnGraph(String componentId, ArtifactDefinition artifactToDelete, NodeTypeEnum type, String instanceId, boolean deleteMandatoryArtifact) {
+    }
 
-		Either<ArtifactDataDefinition, StorageOperationStatus> result = null;
-		Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactToDelete.getArtifactGroupType(), type);
-		EdgeLabelEnum edgeLabel = triple.getLeft();
-		VertexTypeEnum vertexLabel = triple.getRight();
+    public Either<ArtifactDataDefinition, StorageOperationStatus> deleteArtifactWithCloningOnGraph(String componentId, ArtifactDefinition artifactToDelete, NodeTypeEnum type, String instanceId, boolean deleteMandatoryArtifact) {
 
-		Boolean deleteElement = deleteMandatoryArtifact || !(artifactToDelete.getMandatory() || artifactToDelete.getServiceApi());
-		Map<String, ToscaDataDefinition> artifacts = null;
-		GraphVertex parentVertex = null;
-		Either<Map<String, ToscaDataDefinition>, TitanOperationStatus> getArtifactsRes = null;
+        Either<ArtifactDataDefinition, StorageOperationStatus> result = null;
+        Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactToDelete.getArtifactGroupType(), type);
+        EdgeLabelEnum edgeLabel = triple.getLeft();
+        VertexTypeEnum vertexLabel = triple.getRight();
 
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon getting tosca data from graph. Status is {}. ", componentId, getToscaElementRes.right().value());
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
-		}
-		if (result == null) {
-			parentVertex = getToscaElementRes.left().value();
-			getArtifactsRes = this.getDataFromGraph(parentVertex, edgeLabel);
-			if (getArtifactsRes.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getArtifactsRes.right().value()));
-			}
-		}
-		if (result == null) {
-			artifacts = getArtifactsRes.left().value();
-			if (triple.getMiddle()) {
-				artifacts.values().forEach(ma -> ((MapArtifactDataDefinition) ma).getMapToscaDataDefinition().values().forEach(a -> a.setDuplicated(Boolean.TRUE)));
-				MapArtifactDataDefinition artifatcsOnInstance = (MapArtifactDataDefinition) artifacts.get(instanceId);
-				if (artifatcsOnInstance != null && deleteElement) {
-					artifatcsOnInstance.getMapToscaDataDefinition().remove(artifactToDelete.getArtifactLabel());
-				}
-			} else {
-				if (deleteElement) {
-					artifacts.remove(artifactToDelete.getArtifactLabel());
-				}
-				artifacts.values().stream().forEach(a -> ((ArtifactDataDefinition) a).setDuplicated(Boolean.TRUE));
-			}
-			artifactToDelete.setDuplicated(Boolean.TRUE);
-		}
-		if (artifacts != null) {
-			TitanOperationStatus status = titanDao.deleteEdgeByDirection(parentVertex, Direction.OUT, edgeLabel);
-			if (status != TitanOperationStatus.OK) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			} else if (MapUtils.isNotEmpty(artifacts)) {
-				Either<GraphVertex, StorageOperationStatus> assosiateRes = assosiateElementToData(parentVertex, vertexLabel, edgeLabel, artifacts);
-				if (assosiateRes.isRight()) {
-					result = Either.right(result.right().value());
-				}
-			}
-		}
-		if (result == null) {
-			result = Either.left(artifactToDelete);
-		}
-		return result;
-	}
+        Boolean deleteElement = deleteMandatoryArtifact || !(artifactToDelete.getMandatory() || artifactToDelete.getServiceApi());
+        Map<String, ToscaDataDefinition> artifacts = null;
+        GraphVertex parentVertex = null;
+        Either<Map<String, ToscaDataDefinition>, TitanOperationStatus> getArtifactsRes = null;
+
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon getting tosca data from graph. Status is {}. ", componentId, getToscaElementRes.right().value());
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
+        }
+        if (result == null) {
+            parentVertex = getToscaElementRes.left().value();
+            getArtifactsRes = this.getDataFromGraph(parentVertex, edgeLabel);
+            if (getArtifactsRes.isRight()) {
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getArtifactsRes.right().value()));
+            }
+        }
+        if (result == null) {
+            artifacts = getArtifactsRes.left().value();
+            if (triple.getMiddle()) {
+                artifacts.values().forEach(ma -> ((MapArtifactDataDefinition) ma).getMapToscaDataDefinition().values().forEach(a -> a.setDuplicated(Boolean.TRUE)));
+                MapArtifactDataDefinition artifatcsOnInstance = (MapArtifactDataDefinition) artifacts.get(instanceId);
+                if (artifatcsOnInstance != null && deleteElement) {
+                    artifatcsOnInstance.getMapToscaDataDefinition().remove(artifactToDelete.getArtifactLabel());
+                }
+            } else {
+                if (deleteElement) {
+                    artifacts.remove(artifactToDelete.getArtifactLabel());
+                }
+                artifacts.values().stream().forEach(a -> ((ArtifactDataDefinition) a).setDuplicated(Boolean.TRUE));
+            }
+            artifactToDelete.setDuplicated(Boolean.TRUE);
+        }
+        if (artifacts != null) {
+            TitanOperationStatus status = titanDao.deleteEdgeByDirection(parentVertex, Direction.OUT, edgeLabel);
+            if (status != TitanOperationStatus.OK) {
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            } else if (MapUtils.isNotEmpty(artifacts)) {
+                Either<GraphVertex, StorageOperationStatus> associateResult = associateElementToData(parentVertex, vertexLabel, edgeLabel, artifacts);
+                if (associateResult.isRight()) {
+                    result = Either.right(associateResult.right().value());
+                }
+            }
+        }
+        if (result == null) {
+            result = Either.left(artifactToDelete);
+        }
+        return result;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java
index ee1a8a0..5280175 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java
@@ -20,15 +20,8 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
@@ -36,40 +29,39 @@
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.*;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.LifecycleStateEnum;
 import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
+import org.openecomp.sdc.be.model.operations.StorageException;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.util.*;
+import java.util.EnumMap;
+import java.util.stream.Collectors;
 
 /**
  * public abstract class BaseOperation provides base operation functionality and common fields
@@ -77,1212 +69,1220 @@
  */
 public abstract class BaseOperation {
 
-	private static Logger logger = LoggerFactory.getLogger(BaseOperation.class.getName());
+    private static final String FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS = "Failed remove tosca data vertex of the tosca element {} by label {}. Status is {}. ";
+	private static final String FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS = "Failed to get child vertex of the tosca element {} by label {}. Status is {}. ";
+	private static final String FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS = "Failed to get tosca element {} upon adding the properties. Status is {}. ";
+	private static final Logger log = Logger.getLogger(BaseOperation.class.getName());
+    public static final String VF_MODULE = "org.openecomp.groups.VfModule";
 
-	public static final String VF_MODULE = "org.openecomp.groups.VfModule";
+    @Autowired
+    protected TitanDao titanDao;
 
-	@Autowired
-	protected TitanDao titanDao;
+    @Autowired
+    protected NodeTypeOperation nodeTypeOperation;
 
-	@Autowired
-	protected NodeTypeOperation nodeTypeOperation;
+    @Autowired
+    protected TopologyTemplateOperation topologyTemplateOperation;
 
-	@Autowired
-	protected TopologyTemplateOperation topologyTemplateOperation;
+    public void setTitanDao(TitanDao titanDao) {
+        this.titanDao = titanDao;
+    }
+    /**
+     * Returns reference to appropriate toscaTemplateOperation
+     *
+     * @param componentType
+     * @return
+     */
+    public ToscaElementOperation getToscaElementOperation(ComponentTypeEnum componentType) {
+        ToscaElementOperation operation;
+        switch (componentType) {
+        case SERVICE:
+        case RESOURCE:
+            operation = topologyTemplateOperation;
+            break;
+        default:
+            operation = nodeTypeOperation;
+            break;
+        }
+        return operation;
+    }
 
-	public void setTitanDao(TitanDao titanDao) {
-		this.titanDao = titanDao;
-	}
-	/**
-	 * Returns reference to appropriate toscaTemplateOperation
-	 * 
-	 * @param componentType
-	 * @return
-	 */
-	public ToscaElementOperation getToscaElementOperation(ComponentTypeEnum componentType) {
-		ToscaElementOperation operation;
-		switch (componentType) {
-		case SERVICE:
-		case RESOURCE:
-			operation = topologyTemplateOperation;
-			break;
-		default:
-			operation = nodeTypeOperation;
-			break;
-		}
-		return operation;
-	}
+    /**
+     * Returns reference to appropriate toscaTemplateOperation
+     *
+     * @param toscaElementType
+     * @return
+     */
+    public ToscaElementOperation getToscaElementOperation(ToscaElementTypeEnum toscaElementType) {
+        ToscaElementOperation operation;
+        switch (toscaElementType) {
+        case TOPOLOGY_TEMPLATE:
+            operation = topologyTemplateOperation;
+            break;
+        case NODE_TYPE:
+            operation = nodeTypeOperation;
+            break;
+        default:
+            operation = null;
+            break;
+        }
+        return operation;
+    }
 
-	/**
-	 * Returns reference to appropriate toscaTemplateOperation
-	 * 
-	 * @param toscaElementType
-	 * @return
-	 */
-	public ToscaElementOperation getToscaElementOperation(ToscaElementTypeEnum toscaElementType) {
-		ToscaElementOperation operation;
-		switch (toscaElementType) {
-		case TopologyTemplate:
-			operation = topologyTemplateOperation;
-			break;
-		case NodeType:
-			operation = nodeTypeOperation;
-			break;
-		default:
-			operation = null;
-			break;
-		}
-		return operation;
-	}
+    /**
+     * Returns reference to appropriate toscaTemplateOperation
+     *
+     * @param toscaElementType
+     * @return
+     */
+    public ToscaElementOperation getToscaElementOperation(VertexTypeEnum toscaElementType) {
+        ToscaElementOperation operation;
+        switch (toscaElementType) {
+        case TOPOLOGY_TEMPLATE:
+            operation = topologyTemplateOperation;
+            break;
+        case NODE_TYPE:
+            operation = nodeTypeOperation;
+            break;
+        default:
+            operation = null;
+            break;
+        }
+        return operation;
+    }
+    /**
+     * Converts received vertex to User object
+     *
+     * @param ownerV
+     * @return
+     */
+    public User convertToUser(Vertex ownerV) {
+        User owner = new User();
+        owner.setUserId((String) ownerV.property(GraphPropertyEnum.USERID.getProperty()).value());
+        VertexProperty<Object> property = ownerV.property(GraphPropertyEnum.ROLE.getProperty());
+        if(property != null && property.isPresent() ){
+            owner.setRole((String) property.value());
+        }
 
-	/**
-	 * Returns reference to appropriate toscaTemplateOperation
-	 * 
-	 * @param toscaElementType
-	 * @return
-	 */
-	public ToscaElementOperation getToscaElementOperation(VertexTypeEnum toscaElementType) {
-		ToscaElementOperation operation;
-		switch (toscaElementType) {
-		case TOPOLOGY_TEMPLATE:
-			operation = topologyTemplateOperation;
-			break;
-		case NODE_TYPE:
-			operation = nodeTypeOperation;
-			break;
-		default:
-			operation = null;
-			break;
-		}
-		return operation;
-	}
-	/**
-	 * Converts received vertex to User object
-	 * 
-	 * @param ownerV
-	 * @return
-	 */
-	public User convertToUser(Vertex ownerV) {
-		User owner = new User();
-		owner.setUserId((String) ownerV.property(GraphPropertyEnum.USERID.getProperty()).value());
-		VertexProperty<Object> property = ownerV.property(GraphPropertyEnum.ROLE.getProperty());
-		if(property != null && property.isPresent() ){
-			owner.setRole((String) property.value());
-		}
-		
-		property = ownerV.property(GraphPropertyEnum.FIRST_NAME.getProperty()); 
-		if(property != null && property.isPresent() ){
-			owner.setFirstName((String) ownerV.property(GraphPropertyEnum.FIRST_NAME.getProperty()).value());
-		}
-		
-		property = ownerV.property(GraphPropertyEnum.LAST_NAME.getProperty());
-		if( property != null && property.isPresent() ){
-			owner.setLastName((String) ownerV.property(GraphPropertyEnum.LAST_NAME.getProperty()).value());
-		}
-		
-		property = ownerV.property(GraphPropertyEnum.EMAIL.getProperty());
-		if( property != null && property.isPresent() ){
-			owner.setEmail((String) ownerV.property(GraphPropertyEnum.EMAIL.getProperty()).value());
-		}
-		
-		property = ownerV.property(GraphPropertyEnum.LAST_LOGIN_TIME.getProperty());
-		if( property != null && property.isPresent() ){
-			owner.setLastLoginTime((Long) ownerV.property(GraphPropertyEnum.LAST_LOGIN_TIME.getProperty()).value());
-		}
-		return owner;
-	}
+        property = ownerV.property(GraphPropertyEnum.FIRST_NAME.getProperty());
+        if(property != null && property.isPresent() ){
+            owner.setFirstName((String) ownerV.property(GraphPropertyEnum.FIRST_NAME.getProperty()).value());
+        }
 
-	protected <T extends ToscaDataDefinition> Either<Map<String, T>, TitanOperationStatus> getDataFromGraph(GraphVertex componentV, EdgeLabelEnum edgelabel) {
-		Either<Pair<GraphVertex, Map<String, T>>, TitanOperationStatus> dataVertex = getDataAndVertexFromGraph(componentV, edgelabel);
-		if (dataVertex.isRight()) {
-			return Either.right(dataVertex.right().value());
-		}
-		Map<String, T> properties = dataVertex.left().value().getRight();
-		return Either.left(properties);
-	}
+        property = ownerV.property(GraphPropertyEnum.LAST_NAME.getProperty());
+        if( property != null && property.isPresent() ){
+            owner.setLastName((String) ownerV.property(GraphPropertyEnum.LAST_NAME.getProperty()).value());
+        }
 
-	@SuppressWarnings("unchecked")
-	protected <T extends ToscaDataDefinition> Either<Pair<GraphVertex, Map<String, T>>, TitanOperationStatus> getDataAndVertexFromGraph(GraphVertex componentV, EdgeLabelEnum edgelabel) {
-		Either<GraphVertex, TitanOperationStatus> dataVertex = getDataVertex(componentV, edgelabel);
-		if (dataVertex.isRight()) {
-			return Either.right(dataVertex.right().value());
-		}
-		GraphVertex propV = dataVertex.left().value();
-		Map<String, T> properties = (Map<String, T>) propV.getJson();
-		Pair<GraphVertex, Map<String, T>> pair = new ImmutablePair<GraphVertex, Map<String, T>>(propV, properties);
-		return Either.left(pair);
-	}
+        property = ownerV.property(GraphPropertyEnum.EMAIL.getProperty());
+        if( property != null && property.isPresent() ){
+            owner.setEmail((String) ownerV.property(GraphPropertyEnum.EMAIL.getProperty()).value());
+        }
 
-	protected <T extends ToscaDataDefinition> Either<GraphVertex, TitanOperationStatus> getDataVertex(GraphVertex componentV, EdgeLabelEnum edgelabel) {
-		Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, edgelabel, JsonParseFlagEnum.ParseJson);
-		if (childVertex.isRight()) {
-			if (childVertex.right().value() != TitanOperationStatus.NOT_FOUND) {
-				logger.debug("failed to fetch {} for tosca element with id {}, error {}", edgelabel, componentV.getUniqueId(), childVertex.right().value());
-			}
-			return Either.right(childVertex.right().value());
-		}
-		GraphVertex propV = childVertex.left().value();
-		return Either.left(propV);
-	}
+        property = ownerV.property(GraphPropertyEnum.LAST_LOGIN_TIME.getProperty());
+        if( property != null && property.isPresent() ){
+            owner.setLastLoginTime((Long) ownerV.property(GraphPropertyEnum.LAST_LOGIN_TIME.getProperty()).value());
+        }
+        return owner;
+    }
 
-	/**
-	 * Returns tosca data belonging to tosca element specified by uid according received label
-	 * 
-	 * @param toscaElementUid
-	 * @param edgelabel
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> Either<Map<String, T>, TitanOperationStatus> getDataFromGraph(String toscaElementUid, EdgeLabelEnum edgelabel) {
+    protected <T extends ToscaDataDefinition> Either<Map<String, T>, TitanOperationStatus> getDataFromGraph(GraphVertex componentV, EdgeLabelEnum edgelabel) {
+        Either<Pair<GraphVertex, Map<String, T>>, TitanOperationStatus> dataVertex = getDataAndVertexFromGraph(componentV, edgelabel);
+        if (dataVertex.isRight()) {
+            return Either.right(dataVertex.right().value());
+        }
+        Map<String, T> properties = dataVertex.left().value().getRight();
+        return Either.left(properties);
+    }
 
-		Either<Map<String, T>, TitanOperationStatus> result = null;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+    @SuppressWarnings("unchecked")
+    protected <T extends ToscaDataDefinition> Either<Pair<GraphVertex, Map<String, T>>, TitanOperationStatus> getDataAndVertexFromGraph(GraphVertex componentV, EdgeLabelEnum edgelabel) {
+        Either<GraphVertex, TitanOperationStatus> dataVertex = getDataVertex(componentV, edgelabel);
+        if (dataVertex.isRight()) {
+            return Either.right(dataVertex.right().value());
+        }
+        GraphVertex propV = dataVertex.left().value();
+        Map<String, T> properties = (Map<String, T>) propV.getJson();
+        Pair<GraphVertex, Map<String, T>> pair = new ImmutablePair<>(propV, properties);
+        return Either.left(pair);
+    }
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon getting tosca data from graph. Status is {}. ", toscaElementUid, status);
-			result = Either.right(status);
-		}
-		if (result == null) {
-			result = getDataFromGraph(getToscaElementRes.left().value(), edgelabel);
-		}
-		return result;
-	}
+    protected <T extends ToscaDataDefinition> Either<GraphVertex, TitanOperationStatus> getDataVertex(GraphVertex componentV, EdgeLabelEnum edgelabel) {
+        Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, edgelabel, JsonParseFlagEnum.ParseJson);
+        if (childVertex.isRight()) {
+            if (childVertex.right().value() != TitanOperationStatus.NOT_FOUND) {
+                log.debug("failed to fetch {} for tosca element with id {}, error {}", edgelabel, componentV.getUniqueId(), childVertex.right().value());
+            }
+            return Either.right(childVertex.right().value());
+        }
+        GraphVertex propV = childVertex.left().value();
+        return Either.left(propV);
+    }
 
-	public Either<GraphVertex, TitanOperationStatus> findUserVertex(String userId) {
-		return titanDao.getVertexByPropertyAndLabel(GraphPropertyEnum.USERID, userId, VertexTypeEnum.USER, JsonParseFlagEnum.NoParse);
-	}
+    /**
+     * Returns tosca data belonging to tosca element specified by uid according received label
+     *
+     * @param toscaElementUid
+     * @param edgelabel
+     * @return
+     */
+    public <T extends ToscaDataDefinition> Either<Map<String, T>, TitanOperationStatus> getDataFromGraph(String toscaElementUid, EdgeLabelEnum edgelabel) {
 
-	/**
-	 * 
-	 * @param elemementId
-	 * @param label
-	 * @return
-	 */
-	public Either<Boolean, StorageOperationStatus> isCloneNeeded(String elemementId, EdgeLabelEnum label) {
-		Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(elemementId);
-		if (vertexById.isRight()) {
-			logger.debug("Failed to fetch element by id {} error {}", elemementId, vertexById.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexById.right().value()));
-		}
-		GraphVertex toscaElementVertex = vertexById.left().value();
-		Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(toscaElementVertex, label, JsonParseFlagEnum.NoParse);
-		if (childVertex.isRight()) {
-			if (childVertex.right().value() != TitanOperationStatus.NOT_FOUND) {
-				logger.debug("failed to fetch {} for tosca element with id {}, error {}", label, toscaElementVertex.getUniqueId(), childVertex.right().value());
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value()));
-			}
-			return Either.left(Boolean.FALSE);
-		}
-		GraphVertex dataVertex = childVertex.left().value();
-		Iterator<Edge> edges = dataVertex.getVertex().edges(Direction.IN, label.name());
-		int edgeCount = 0;
-		while (edges.hasNext()) {
-			edges.next();
-			++edgeCount;
-		}
-		if (edgeCount > 1) {
-			return Either.left(Boolean.TRUE);
-		} else {
-			return Either.left(Boolean.FALSE);
-		}
-	}
+        Either<Map<String, T>, TitanOperationStatus> result = null;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
 
-	protected Either<GraphVertex, TitanOperationStatus> updateOrCopyOnUpdate(GraphVertex dataVertex, GraphVertex toscaElementVertex, EdgeLabelEnum label) {
-		Iterator<Edge> edges = dataVertex.getVertex().edges(Direction.IN, label.name());
-		int edgeCount = 0;
-		Edge edgeToRemove = null;
-		while (edges.hasNext()) {
-			Edge edge = edges.next();
-			++edgeCount;
-			Vertex outVertex = edge.outVertex();
-			String outId = (String) titanDao.getProperty((TitanVertex) outVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
-			if (toscaElementVertex.getUniqueId().equals(outId)) {
-				edgeToRemove = edge;
-			}
-		}
-		if (edgeToRemove == null) {
-			logger.debug("No edges {} from vertex {} to vertex {}", label, toscaElementVertex.getUniqueId(), dataVertex.getUniqueId());
-			return Either.right(TitanOperationStatus.GENERAL_ERROR);
-		}
-		switch (edgeCount) {
-		case 0:
-			// error
-			logger.debug("No edges {} to vertex {}", label, dataVertex.getUniqueId());
-			return Either.right(TitanOperationStatus.GENERAL_ERROR);
-		case 1:
-			// update
-			logger.trace("Only one edge {} to vertex {}. Update vertex", label, dataVertex.getUniqueId());
-			return titanDao.updateVertex(dataVertex);
-		default:
-			// copy on update
-			logger.trace("More than one edge {} to vertex {}. Need to clone vertex", label, dataVertex.getUniqueId());
-			return cloneDataVertex(dataVertex, toscaElementVertex, label, edgeToRemove);
-		}
-	}
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon getting tosca data from graph. Status is {}. ", toscaElementUid, status);
+            result = Either.right(status);
+        }
+        if (result == null) {
+            result = getDataFromGraph(getToscaElementRes.left().value(), edgelabel);
+        }
+        return result;
+    }
 
-	private Either<GraphVertex, TitanOperationStatus> cloneDataVertex(GraphVertex dataVertex, GraphVertex toscaElementVertex, EdgeLabelEnum label, Edge edgeToRemove) {
-		GraphVertex newDataVertex = new GraphVertex(dataVertex.getLabel());
-		String id = IdBuilderUtils.generateChildId(toscaElementVertex.getUniqueId(), dataVertex.getLabel());
-		newDataVertex.setUniqueId(id);
-		newDataVertex.cloneData(dataVertex);
+    public Either<GraphVertex, TitanOperationStatus> findUserVertex(String userId) {
+        return titanDao.getVertexByPropertyAndLabel(GraphPropertyEnum.USERID, userId, VertexTypeEnum.USER, JsonParseFlagEnum.NoParse);
+    }
 
-		Either<GraphVertex, TitanOperationStatus> createVertex = titanDao.createVertex(newDataVertex);
-		if (createVertex.isRight()) {
-			logger.debug("Failed to clone data vertex for {} error {}", dataVertex.getUniqueId(), createVertex.right().value());
-			return createVertex;
-		}
-		newDataVertex = createVertex.left().value();
-		TitanOperationStatus createEdge = titanDao.createEdge(toscaElementVertex, newDataVertex, label, titanDao.getEdgeProperties(edgeToRemove));
-		if (createEdge != TitanOperationStatus.OK) {
-			logger.debug("Failed to associate vertex {} to vertex {}, error {}", toscaElementVertex.getUniqueId(), newDataVertex.getUniqueId(), createEdge);
-			return Either.right(createEdge);
-		}
-		edgeToRemove.remove();
-		return Either.left(newDataVertex);
-	}
+    /**
+     *
+     * @param elemementId
+     * @param label
+     * @return
+     */
+    public Either<Boolean, StorageOperationStatus> isCloneNeeded(String elemementId, EdgeLabelEnum label) {
+        Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(elemementId);
+        if (vertexById.isRight()) {
+            log.debug("Failed to fetch element by id {} error {}", elemementId, vertexById.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexById.right().value()));
+        }
+        GraphVertex toscaElementVertex = vertexById.left().value();
+        Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(toscaElementVertex, label, JsonParseFlagEnum.NoParse);
+        if (childVertex.isRight()) {
+            if (childVertex.right().value() != TitanOperationStatus.NOT_FOUND) {
+                log.debug("failed to fetch {} for tosca element with id {}, error {}", label, toscaElementVertex.getUniqueId(), childVertex.right().value());
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value()));
+            }
+            return Either.left(Boolean.FALSE);
+        }
+        GraphVertex dataVertex = childVertex.left().value();
+        Iterator<Edge> edges = dataVertex.getVertex().edges(Direction.IN, label.name());
+        int edgeCount = 0;
+        while (edges.hasNext()) {
+            edges.next();
+            ++edgeCount;
+        }
+        if (edgeCount > 1) {
+            return Either.left(Boolean.TRUE);
+        } else {
+            return Either.left(Boolean.FALSE);
+        }
+    }
 
-	public Either<GraphVertex, StorageOperationStatus> assosiateElementToData(GraphVertex element, VertexTypeEnum vertexLabel, EdgeLabelEnum edgeLabel, Map<String, ? extends ToscaDataDefinition> data) {
-		GraphVertex dataV = new GraphVertex(vertexLabel);
-		String id = IdBuilderUtils.generateChildId(element.getUniqueId(), vertexLabel);
-		dataV.setUniqueId(id);
-		dataV.setJson(data);
-		Either<GraphVertex, TitanOperationStatus> createVertex = titanDao.createVertex(dataV);
-		if (createVertex.isRight()) {
-			logger.trace("Failed to create {} vertex for type node {}", vertexLabel, element.getUniqueId());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createVertex.right().value()));
-		}
-		dataV = createVertex.left().value();
-		TitanOperationStatus createEdgeStatus = titanDao.createEdge(element.getVertex(), dataV.getVertex(), edgeLabel, new HashMap<>());
-		if (createEdgeStatus != TitanOperationStatus.OK) {
-			logger.trace("Failed to create {} vertex for type node {}", vertexLabel, element.getUniqueId());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeStatus));
-		}
-		return Either.left(dataV);
-	}
+    protected Either<GraphVertex, TitanOperationStatus> updateOrCopyOnUpdate(GraphVertex dataVertex, GraphVertex toscaElementVertex, EdgeLabelEnum label) {
+        Iterator<Edge> edges = dataVertex.getVertex().edges(Direction.IN, label.name());
+        int edgeCount = 0;
+        Edge edgeToRemove = null;
+        while (edges.hasNext()) {
+            Edge edge = edges.next();
+            ++edgeCount;
+            Vertex outVertex = edge.outVertex();
+            String outId = (String) titanDao.getProperty((TitanVertex) outVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
+            if (toscaElementVertex.getUniqueId().equals(outId)) {
+                edgeToRemove = edge;
+            }
+        }
+        if (edgeToRemove == null) {
+            log.debug("No edges {} from vertex {} to vertex {}", label, toscaElementVertex.getUniqueId(), dataVertex.getUniqueId());
+            return Either.right(TitanOperationStatus.GENERAL_ERROR);
+        }
+        switch (edgeCount) {
+        case 0:
+            // error
+            log.debug("No edges {} to vertex {}", label, dataVertex.getUniqueId());
+            return Either.right(TitanOperationStatus.GENERAL_ERROR);
+        case 1:
+            // update
+            log.trace("Only one edge {} to vertex {}. Update vertex", label, dataVertex.getUniqueId());
+            return titanDao.updateVertex(dataVertex);
+        default:
+            // copy on update
+            log.trace("More than one edge {} to vertex {}. Need to clone vertex", label, dataVertex.getUniqueId());
+            return cloneDataVertex(dataVertex, toscaElementVertex, label, edgeToRemove);
+        }
+    }
 
-	/**
-	 * Adds tosca data element to tosca element according received labels
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaData
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, JsonPresentationFields mapKeyField) {
+    private Either<GraphVertex, TitanOperationStatus> cloneDataVertex(GraphVertex dataVertex, GraphVertex toscaElementVertex, EdgeLabelEnum label, Edge edgeToRemove) {
+        GraphVertex newDataVertex = new GraphVertex(dataVertex.getLabel());
+        String id = IdBuilderUtils.generateChildId(toscaElementVertex.getUniqueId(), dataVertex.getLabel());
+        newDataVertex.cloneData(dataVertex);
+        newDataVertex.setUniqueId(id);
 
-		List<T> toscaDataList = new ArrayList<>();
-		toscaDataList.add(toscaData);
-		return addToscaDataToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
-	}
+        Either<GraphVertex, TitanOperationStatus> createVertex = titanDao.createVertex(newDataVertex);
+        if (createVertex.isRight()) {
+            log.debug("Failed to clone data vertex for {} error {}", dataVertex.getUniqueId(), createVertex.right().value());
+            return createVertex;
+        }
+        newDataVertex = createVertex.left().value();
+        TitanOperationStatus createEdge = titanDao.createEdge(toscaElementVertex, newDataVertex, label, titanDao.getEdgeProperties(edgeToRemove));
+        if (createEdge != TitanOperationStatus.OK) {
+            log.debug("Failed to associate vertex {} to vertex {}, error {}", toscaElementVertex.getUniqueId(), newDataVertex.getUniqueId(), createEdge);
+            return Either.right(createEdge);
+        }
+        edgeToRemove.remove();
+        return Either.left(newDataVertex);
+    }
 
-	/**
-	 * Adds tosca data deep element to tosca element according received labels
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaData
-	 * @param pathKeys
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, List<String> pathKeys,
-			JsonPresentationFields mapKeyField) {
+    public Either<GraphVertex, StorageOperationStatus> associateElementToData(GraphVertex element, VertexTypeEnum vertexLabel, EdgeLabelEnum edgeLabel, Map<String, ? extends ToscaDataDefinition> data) {
+        GraphVertex dataV = new GraphVertex(vertexLabel);
+        String id = IdBuilderUtils.generateChildId(element.getUniqueId(), vertexLabel);
+        dataV.setUniqueId(id);
+        dataV.setJson(data);
+        Either<GraphVertex, TitanOperationStatus> createVertex = titanDao.createVertex(dataV);
+        if (createVertex.isRight()) {
+            log.trace("Failed to create {} vertex for type node {}", vertexLabel, element.getUniqueId());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createVertex.right().value()));
+        }
+        dataV = createVertex.left().value();
+        TitanOperationStatus createEdgeStatus = titanDao.createEdge(element.getVertex(), dataV.getVertex(), edgeLabel, new HashMap<>());
+        if (createEdgeStatus != TitanOperationStatus.OK) {
+            log.trace("Failed to create {} vertex for type node {}", vertexLabel, element.getUniqueId());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeStatus));
+        }
+        return Either.left(dataV);
+    }
 
-		List<T> toscaDataList = new ArrayList<>();
-		toscaDataList.add(toscaData);
-		return addToscaDataDeepElementsToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
-	}
+    /**
+     * Adds tosca data element to tosca element according received labels
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaData
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, JsonPresentationFields mapKeyField) {
 
-	/**
-	 * Converts recieved map of tosca data deep elements to list and adds it to tosca element according received labels
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaDataMap
-	 * @param pathKeys
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, Map<String, T> toscaDataMap, List<String> pathKeys,
-			JsonPresentationFields mapKeyField) {
+        List<T> toscaDataList = new ArrayList<>();
+        toscaDataList.add(toscaData);
+        return addToscaDataToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
+    }
 
-		if (toscaDataMap != null) {
-			return addToscaDataDeepElementsToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataMap.values().stream().collect(Collectors.toList()), pathKeys, mapKeyField);
-		}
-		return StorageOperationStatus.OK;
-	}
+    /**
+     * Adds tosca data deep element to tosca element according received labels
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaData
+     * @param pathKeys
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, List<String> pathKeys,
+            JsonPresentationFields mapKeyField) {
 
-	/**
-	 * Adds list of tosca data deep elements to tosca element according received labels
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaDataList
-	 * @param pathKeys
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, List<String> pathKeys,
-			JsonPresentationFields mapKeyField) {
+        List<T> toscaDataList = new ArrayList<>();
+        toscaDataList.add(toscaData);
+        return addToscaDataDeepElementsToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
+    }
 
-		return updateOrAddToscaDataDeepElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField, false);
-	}
+    /**
+     * Converts recieved map of tosca data deep elements to list and adds it to tosca element according received labels
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaDataMap
+     * @param pathKeys
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, Map<String, T> toscaDataMap, List<String> pathKeys,
+            JsonPresentationFields mapKeyField) {
 
-	/**
-	 * Updates list of tosca data elements of tosca element according received labels
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaData
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, JsonPresentationFields mapKeyField) {
-		List<T> toscaDataList = new ArrayList<>();
-		toscaDataList.add(toscaData);
-		return updateToscaDataOfToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
-	}
+        if (toscaDataMap != null) {
+            return addToscaDataDeepElementsToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataMap.values().stream().collect(Collectors.toList()), pathKeys, mapKeyField);
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	/**
-	 * Updates tosca data deep element of tosca element according received labels
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaData
-	 * @param pathKeys
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, List<String> pathKeys,
-			JsonPresentationFields mapKeyField) {
-		List<T> toscaDataList = new ArrayList<>();
-		toscaDataList.add(toscaData);
-		return updateToscaDataDeepElementsOfToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
-	}
+    /**
+     * Adds list of tosca data deep elements to tosca element according received labels
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaDataList
+     * @param pathKeys
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, List<String> pathKeys,
+            JsonPresentationFields mapKeyField) {
 
-	/**
-	 * Updates tosca data deep elements of tosca element according received labels
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaDataList
-	 * @param pathKeys
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, List<String> pathKeys,
-			JsonPresentationFields mapKeyField) {
+        return updateOrAddToscaDataDeepElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField, false);
+    }
 
-		return updateOrAddToscaDataDeepElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField, true);
-	}
+    /**
+     * Updates list of tosca data elements of tosca element according received labels
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaData
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, JsonPresentationFields mapKeyField) {
+        List<T> toscaDataList = new ArrayList<>();
+        toscaDataList.add(toscaData);
+        return updateToscaDataOfToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
+    }
 
-	/**
-	 * Adds tosca data element to tosca element with specified uid according received labels
-	 * 
-	 * @param toscaElementUid
-	 * @param toscaData
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, JsonPresentationFields mapKeyField) {
+    /**
+     * Updates tosca data deep element of tosca element according received labels
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaData
+     * @param pathKeys
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, List<String> pathKeys,
+            JsonPresentationFields mapKeyField) {
+        List<T> toscaDataList = new ArrayList<>();
+        toscaDataList.add(toscaData);
+        return updateToscaDataDeepElementsOfToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
+    }
 
-		List<T> toscaDataList = new ArrayList<>();
-		toscaDataList.add(toscaData);
-		return addToscaDataToToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
-	}
+    /**
+     * Updates tosca data deep elements of tosca element according received labels
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaDataList
+     * @param pathKeys
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, List<String> pathKeys,
+            JsonPresentationFields mapKeyField) {
 
-	/**
-	 * Adds tosca data deep element to tosca element with specified uid according received labels
-	 * 
-	 * @param toscaElementUid
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaData
-	 * @param pathKeys
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, List<String> pathKeys,
-			JsonPresentationFields mapKeyField) {
+        return updateOrAddToscaDataDeepElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField, true);
+    }
 
-		List<T> toscaDataList = new ArrayList<>();
-		toscaDataList.add(toscaData);
-		return addToscaDataDeepElementsToToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
-	}
+    /**
+     * Adds tosca data element to tosca element with specified uid according received labels
+     *
+     * @param toscaElementUid
+     * @param toscaData
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, JsonPresentationFields mapKeyField) {
 
-	public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, List<String> pathKeys,
-			JsonPresentationFields mapKeyField) {
+        List<T> toscaDataList = new ArrayList<>();
+        toscaDataList.add(toscaData);
+        return addToscaDataToToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
+    }
 
-		List<T> toscaDataList = new ArrayList<>();
-		toscaDataList.add(toscaData);
-		return updateToscaDataDeepElementsOfToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
-	}
+    /**
+     * Adds tosca data deep element to tosca element with specified uid according received labels
+     *
+     * @param toscaElementUid
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaData
+     * @param pathKeys
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, List<String> pathKeys,
+            JsonPresentationFields mapKeyField) {
 
-	public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, List<String> pathKeys,
-			JsonPresentationFields mapKeyField) {
+        List<T> toscaDataList = new ArrayList<>();
+        toscaDataList.add(toscaData);
+        return addToscaDataDeepElementsToToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
+    }
 
-		StorageOperationStatus statusRes = null;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+    public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, List<String> pathKeys,
+            JsonPresentationFields mapKeyField) {
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", toscaElementUid, status);
-			statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
-			statusRes = updateToscaDataDeepElementsOfToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
-		}
-		if (statusRes == null) {
-			statusRes = StorageOperationStatus.OK;
-		}
-		return statusRes;
-	}
+        List<T> toscaDataList = new ArrayList<>();
+        toscaDataList.add(toscaData);
+        return updateToscaDataDeepElementsOfToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
+    }
 
-	StorageOperationStatus overrideToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, Map<String, ? extends ToscaDataDefinition> toscaData) {
-		return titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse)
-				.left()
-				.bind(graphVertex -> overrideToscaElementData(graphVertex, toscaData, edgeLabel))
-				.either(graphVertex -> StorageOperationStatus.OK,
-						DaoStatusConverter::convertTitanStatusToStorageStatus);
-	}
+    public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, List<String> pathKeys,
+            JsonPresentationFields mapKeyField) {
 
-	private Either<GraphVertex, TitanOperationStatus> overrideToscaElementData(GraphVertex toscaElement, Map<String, ? extends ToscaDataDefinition> toscaData, EdgeLabelEnum edgeLabelEnum) {
-		return titanDao.getChildVertex(toscaElement, edgeLabelEnum, JsonParseFlagEnum.ParseJson)
-				.left()
-				.bind(dataVertex -> overrideToscaElementData(dataVertex, toscaElement, toscaData, edgeLabelEnum))
-				.right()
-				.map(err -> logAndReturn(err, "failed to override tosca data for element {} of type {}. status: {}", toscaElement.getUniqueId(), edgeLabelEnum, err));
-	}
+        StorageOperationStatus statusRes = null;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
 
-	private Either<GraphVertex, TitanOperationStatus> overrideToscaElementData(GraphVertex dataElement, GraphVertex toscaElement, Map<String, ? extends ToscaDataDefinition> toscaData, EdgeLabelEnum edgeLabelEnum) {
-		dataElement.setJson(toscaData);
-		return updateOrCopyOnUpdate(dataElement, toscaElement, edgeLabelEnum);
-	}
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
+            statusRes = updateToscaDataDeepElementsOfToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
+        }
+        if (statusRes == null) {
+            statusRes = StorageOperationStatus.OK;
+        }
+        return statusRes;
+    }
 
-	/**
-	 * Adds list of tosca data deep elements to tosca element with specified uid according received labels
-	 * 
-	 * @param toscaElementUid
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaDataList
-	 * @param pathKeys
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, List<String> pathKeys,
-			JsonPresentationFields mapKeyField) {
+    StorageOperationStatus overrideToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, Map<String, ? extends ToscaDataDefinition> toscaData) {
+        return titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse)
+                .left()
+                .bind(graphVertex -> overrideToscaElementData(graphVertex, toscaData, edgeLabel))
+                .either(graphVertex -> StorageOperationStatus.OK,
+                        DaoStatusConverter::convertTitanStatusToStorageStatus);
+    }
 
-		StorageOperationStatus statusRes = null;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+    private Either<GraphVertex, TitanOperationStatus> overrideToscaElementData(GraphVertex toscaElement, Map<String, ? extends ToscaDataDefinition> toscaData, EdgeLabelEnum edgeLabelEnum) {
+        return titanDao.getChildVertex(toscaElement, edgeLabelEnum, JsonParseFlagEnum.ParseJson)
+                .left()
+                .bind(dataVertex -> overrideToscaElementData(dataVertex, toscaElement, toscaData, edgeLabelEnum))
+                .right()
+                .map(err -> logAndReturn(err, "failed to override tosca data for element {} of type {}. status: {}", toscaElement.getUniqueId(), edgeLabelEnum, err));
+    }
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", toscaElementUid, status);
-			statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
-			statusRes = addToscaDataDeepElementsToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
-		}
-		if (statusRes == null) {
-			statusRes = StorageOperationStatus.OK;
-		}
-		return statusRes;
-	}
+    private Either<GraphVertex, TitanOperationStatus> overrideToscaElementData(GraphVertex dataElement, GraphVertex toscaElement, Map<String, ? extends ToscaDataDefinition> toscaData, EdgeLabelEnum edgeLabelEnum) {
+        dataElement.setJson(toscaData);
+        return updateOrCopyOnUpdate(dataElement, toscaElement, edgeLabelEnum);
+    }
 
-	public <T extends ToscaDataDefinition> StorageOperationStatus deleteToscaDataDeepElementsBlockToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String key) {
+    /**
+     * Adds list of tosca data deep elements to tosca element with specified uid according received labels
+     *
+     * @param toscaElementUid
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaDataList
+     * @param pathKeys
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, List<String> pathKeys,
+            JsonPresentationFields mapKeyField) {
 
-		StorageOperationStatus statusRes = null;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+        StorageOperationStatus statusRes = null;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", toscaElementUid, status);
-			statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (statusRes == null) {
-			statusRes = deleteToscaDataDeepElementsBlockToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, key);
-		}
-		if (statusRes == null) {
-			statusRes = StorageOperationStatus.OK;
-		}
-		return statusRes;
-	}
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
+            statusRes = addToscaDataDeepElementsToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
+        }
+        if (statusRes == null) {
+            statusRes = StorageOperationStatus.OK;
+        }
+        return statusRes;
+    }
 
-	public <T extends ToscaDataDefinition> StorageOperationStatus deleteToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String key) {
+	public <T extends ToscaDataDefinition> StorageOperationStatus deleteToscaDataDeepElementsBlockOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String key) {
 
-		StorageOperationStatus result = null;
-		GraphVertex toscaDataVertex = null;
-		Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
-		if (toscaDataVertexRes.isRight()) {
-			TitanOperationStatus status = toscaDataVertexRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get child vertex of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, status);
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
-		}
-		if (result == null) {
-			toscaDataVertex = toscaDataVertexRes.left().value();
-			result = deleteDeepElementsBlock(toscaDataVertex, key);
-		}
-		if (result == null) {
-			Either<GraphVertex, TitanOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
-			if (updateOrCopyRes.isRight()) {
-				TitanOperationStatus status = updateOrCopyRes.right().value();
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete tosca data block {} from the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), status);
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+        StorageOperationStatus statusRes = null;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (statusRes == null) {
+            statusRes = deleteToscaDataDeepElementsBlockToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, key);
+        }
+        if (statusRes == null) {
+            statusRes = StorageOperationStatus.OK;
+        }
+        return statusRes;
+    }
+
+    public <T extends ToscaDataDefinition> StorageOperationStatus deleteToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String key) {
+
+        StorageOperationStatus result = null;
+        GraphVertex toscaDataVertex = null;
+        Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
+        if (toscaDataVertexRes.isRight()) {
+            TitanOperationStatus status = toscaDataVertexRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS, toscaElement.getUniqueId(), edgeLabel, status);
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
+        }
+        if (result == null) {
+            toscaDataVertex = toscaDataVertexRes.left().value();
+            result = deleteDeepElementsBlock(toscaDataVertex, key);
+        }
+        if (result == null) {
+            Either<GraphVertex, TitanOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
+            if (updateOrCopyRes.isRight()) {
+                TitanOperationStatus status = updateOrCopyRes.right().value();
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete tosca data block {} from the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), status);
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+            }
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsBlockToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, MapDataDefinition toscaDataMap, String key) {
+
+        StorageOperationStatus statusRes = null;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (statusRes == null && toscaDataMap != null) {
+            statusRes = addToscaDataDeepElementsBlockToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataMap, key);
+        }
+        if (statusRes == null) {
+            statusRes = StorageOperationStatus.OK;
+        }
+        return statusRes;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, MapDataDefinition toscaDataMap, String key) {
+
+        StorageOperationStatus result = null;
+        GraphVertex toscaDataVertex = null;
+        Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
+        if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != TitanOperationStatus.NOT_FOUND) {
+            TitanOperationStatus status = toscaDataVertexRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS, toscaElement.getUniqueId(), edgeLabel, status);
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
+        }
+        if (result == null && toscaDataVertexRes.isLeft()) {
+                toscaDataVertex = toscaDataVertexRes.left().value();
+                result = addDeepElementsBlock(toscaDataVertex, toscaDataMap, key);
+            
+        }
+        if (result == null) {
+            if (toscaDataVertex != null) {
+                Either<GraphVertex, TitanOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
+                if (updateOrCopyRes.isRight()) {
+                    TitanOperationStatus status = updateOrCopyRes.right().value();
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data {} to the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), status);
+                    result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+                }
+            } else {
+                Map<String, MapDataDefinition> data = new HashMap<>();
+                data.put(key, toscaDataMap);
+                Either<GraphVertex, StorageOperationStatus> createRes = associateElementToData(toscaElement, vertexLabel, edgeLabel, data);
+                if (createRes.isRight()) {
+                    StorageOperationStatus status = createRes.right().value();
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to assosiate tosca data {} of the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), status);
+                    result = status;
+                }
+            }
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
+
+    /**
+     *
+     * @param toscaElementId the id of the tosca element data container
+     * @param edgeLabel the edge label of the data type to update
+     * @param toscaDataMap the data to update
+     * @param key the key in the json object where the map object block resides
+     * @return the status of the update operation
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsBlockToToscaElement(String toscaElementId, EdgeLabelEnum edgeLabel, MapDataDefinition<T> toscaDataMap, String key) {
+        return titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse)
+                .either(toscaElement -> updateToscaDataDeepElementsBlockToToscaElement(toscaElement, edgeLabel, toscaDataMap, key),
+                        DaoStatusConverter::convertTitanStatusToStorageStatus);
+    }
 
-	@SuppressWarnings("rawtypes")
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsBlockToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, MapDataDefinition toscaDataMap, String key) {
+    private <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, MapDataDefinition<T> toscaDataMap, String key) {
+        return titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson)
+                .left()
+                .bind(dataVertex -> updateToscaDataDeepElementsBlockToToscaElement(toscaElement, dataVertex, edgeLabel, toscaDataMap, key))
+                .either(updatedVertex -> StorageOperationStatus.OK,
+                        DaoStatusConverter::convertTitanStatusToStorageStatus);
+    }
 
-		StorageOperationStatus statusRes = null;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+    private <T extends ToscaDataDefinition> Either<GraphVertex, TitanOperationStatus> updateToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement, GraphVertex dataElement, EdgeLabelEnum edgeLabel, MapDataDefinition<T> toscaDataMap, String key) {
+        Map<String, T> mapToscaDataDefinition = toscaDataMap.getMapToscaDataDefinition();
+        updateDeepElements(dataElement, mapToscaDataDefinition, Collections.singletonList(key));
+        return updateOrCopyOnUpdate(dataElement, toscaElement, edgeLabel)
+                .right()
+                .map(err -> logAndReturn(err, "failed while trying to update data vertex from tosca element {}, of type {} . status {}", toscaElement.getUniqueId(), edgeLabel, err));
+    }
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", toscaElementUid, status);
-			statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (statusRes == null && toscaDataMap != null) {
-			statusRes = addToscaDataDeepElementsBlockToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataMap, key);
-		}
-		if (statusRes == null) {
-			statusRes = StorageOperationStatus.OK;
-		}
-		return statusRes;
-	}
+    /**
+     * Updates tosca data element of tosca element by specified uid according received labels
+     *
+     * @param toscaElementUid
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaData
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, JsonPresentationFields mapKeyField) {
 
-	@SuppressWarnings("rawtypes")
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, MapDataDefinition toscaDataMap, String key) {
+        List<T> toscaDataList = new ArrayList<>();
+        toscaDataList.add(toscaData);
+        return updateToscaDataOfToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
+    }
 
-		StorageOperationStatus result = null;
-		GraphVertex toscaDataVertex = null;
-		Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
-		if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != TitanOperationStatus.NOT_FOUND) {
-			TitanOperationStatus status = toscaDataVertexRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get child vertex of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, status);
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
-		}
-		if (result == null) {
-			if (toscaDataVertexRes.isLeft()) {
-				toscaDataVertex = toscaDataVertexRes.left().value();
-				result = addDeepElementsBlock(toscaDataVertex, toscaDataMap, key);
-			}
-		}
-		if (result == null) {
-			if (toscaDataVertex != null) {
-				Either<GraphVertex, TitanOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
-				if (updateOrCopyRes.isRight()) {
-					TitanOperationStatus status = updateOrCopyRes.right().value();
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to add tosca data {} to the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), status);
-					result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-				}
-			} else {
-				Map<String, MapDataDefinition> data = new HashMap<>();
-				data.put(key, toscaDataMap);
-				Either<GraphVertex, StorageOperationStatus> createRes = assosiateElementToData(toscaElement, vertexLabel, edgeLabel, data);
-				if (createRes.isRight()) {
-					StorageOperationStatus status = createRes.right().value();
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to assosiate tosca data {} of the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), status);
-					result = status;
-				}
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+    /**
+     * Updates list of tosca data elements belonging to tosca element with specified uid according received labels
+     *
+     * @param toscaElementUid
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaDataList
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, JsonPresentationFields mapKeyField) {
 
-	/**
-	 *
-	 * @param toscaElementId the id of the tosca element data container
-	 * @param edgeLabel the edge label of the data type to update
-	 * @param toscaDataMap the data to update
-	 * @param key the key in the json object where the map object block resides
-	 * @return the status of the update operation
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsBlockToToscaElement(String toscaElementId, EdgeLabelEnum edgeLabel, MapDataDefinition<T> toscaDataMap, String key) {
-		return titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse)
-				.either(toscaElement -> updateToscaDataDeepElementsBlockToToscaElement(toscaElement, edgeLabel, toscaDataMap, key),
-						DaoStatusConverter::convertTitanStatusToStorageStatus);
-	}
+        StorageOperationStatus statusRes = null;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
 
-	private <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, MapDataDefinition<T> toscaDataMap, String key) {
-		return titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson)
-				.left()
-				.bind(dataVertex -> updateToscaDataDeepElementsBlockToToscaElement(toscaElement, dataVertex, edgeLabel, toscaDataMap, key))
-				.either(updatedVertex -> StorageOperationStatus.OK,
-						DaoStatusConverter::convertTitanStatusToStorageStatus);
-	}
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
+            statusRes = updateToscaDataOfToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, mapKeyField);
+        }
+        if (statusRes == null) {
+            statusRes = StorageOperationStatus.OK;
+        }
+        return statusRes;
+    }
 
-	private <T extends ToscaDataDefinition> Either<GraphVertex, TitanOperationStatus> updateToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement, GraphVertex dataElement, EdgeLabelEnum edgeLabel, MapDataDefinition<T> toscaDataMap, String key) {
-		Map<String, T> mapToscaDataDefinition = toscaDataMap.getMapToscaDataDefinition();
-		updateDeepElements(dataElement, mapToscaDataDefinition, Collections.singletonList(key));
-		return updateOrCopyOnUpdate(dataElement, toscaElement, edgeLabel)
-				.right()
-				.map(err -> logAndReturn(err, "failed while trying to update data vertex from tosca element {}, of type {} . status {}", toscaElement.getUniqueId(), edgeLabel, err));
-	}
+    /**
+     * Adds list of tosca data elements to tosca element with specified uid according received labels
+     *
+     * @param toscaElementUid
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaDataList
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, JsonPresentationFields mapKeyField) {
 
-	/**
-	 * Updates tosca data element of tosca element by specified uid according received labels
-	 * 
-	 * @param toscaElementUid
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaData
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, T toscaData, JsonPresentationFields mapKeyField) {
+        StorageOperationStatus statusRes = null;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
 
-		List<T> toscaDataList = new ArrayList<>();
-		toscaDataList.add(toscaData);
-		return updateToscaDataOfToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
-	}
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
+            statusRes = addToscaDataToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, mapKeyField);
+        }
+        if (statusRes == null) {
+            statusRes = StorageOperationStatus.OK;
+        }
+        return statusRes;
+    }
 
-	/**
-	 * Updates list of tosca data elements belonging to tosca element with specified uid according received labels
-	 * 
-	 * @param toscaElementUid
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaDataList
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, JsonPresentationFields mapKeyField) {
+    /**
+     * Converts recieved map of tosca data elements to list and adds it to tosca element according received labels
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaDataMap
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, Map<String, T> toscaDataMap, JsonPresentationFields mapKeyField) {
 
-		StorageOperationStatus statusRes = null;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+        return addToscaDataToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataMap.values().stream().collect(Collectors.toList()), mapKeyField);
+    }
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", toscaElementUid, status);
-			statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
-			statusRes = updateToscaDataOfToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, mapKeyField);
-		}
-		if (statusRes == null) {
-			statusRes = StorageOperationStatus.OK;
-		}
-		return statusRes;
-	}
+    /**
+     * Adds list of tosca data elements to tosca element according received labels
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaDataList
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, JsonPresentationFields mapKeyField) {
 
-	/**
-	 * Adds list of tosca data elements to tosca element with specified uid according received labels
-	 * 
-	 * @param toscaElementUid
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaDataList
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, JsonPresentationFields mapKeyField) {
+        return updateOrAddToscaData(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField, false);
+    }
 
-		StorageOperationStatus statusRes = null;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+    /**
+     * Updates list of tosca data elements belonging to tosca element according received labels
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param toscaDataList
+     * @param mapKeyField
+     * @return
+     */
+    public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, JsonPresentationFields mapKeyField) {
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", toscaElementUid, status);
-			statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
-			statusRes = addToscaDataToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, mapKeyField);
-		}
-		if (statusRes == null) {
-			statusRes = StorageOperationStatus.OK;
-		}
-		return statusRes;
-	}
+        return updateOrAddToscaData(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField, true);
+    }
 
-	/**
-	 * Converts recieved map of tosca data elements to list and adds it to tosca element according received labels
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaDataMap
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, Map<String, T> toscaDataMap, JsonPresentationFields mapKeyField) {
+    public boolean hasEdgeOfType(GraphVertex toscaElement, EdgeLabelEnum edgeLabel) {
+        Either<GraphVertex, TitanOperationStatus> vertex = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
+        return vertex.isLeft();
+    }
 
-		return addToscaDataToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataMap.values().stream().collect(Collectors.toList()), mapKeyField);
-	}
+    @SuppressWarnings("unchecked")
+    private <T extends ToscaDataDefinition> StorageOperationStatus updateOrAddToscaData(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, JsonPresentationFields mapKeyField, boolean isUpdate) {
+        StorageOperationStatus result = null;
+        GraphVertex toscaDataVertex = null;
+        Map<String, T> existingToscaDataMap = null;
+        Either<Map<String, T>, StorageOperationStatus> validateRes = null;
+        Map<String, T> mergedToscaDataMap;
+        Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
+        if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != TitanOperationStatus.NOT_FOUND) {
+            TitanOperationStatus status = toscaDataVertexRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS, toscaElement.getUniqueId(), edgeLabel, status);
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
+        }
+        if (result == null) {
+            if (toscaDataVertexRes.isLeft()) {
+                toscaDataVertex = toscaDataVertexRes.left().value();
+                existingToscaDataMap = (Map<String, T>) toscaDataVertex.getJson();
+            }
 
-	/**
-	 * Adds list of tosca data elements to tosca element according received labels
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaDataList
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, JsonPresentationFields mapKeyField) {
+             validateRes = validateMergeToscaData(toscaElement, toscaDataList, mapKeyField, existingToscaDataMap, isUpdate);
+            if (validateRes.isRight()) {
+                result = validateRes.right().value();
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed validate tosca data upon adding to tosca element {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, result);
+            }
+        }
+        if (result == null) {
+            mergedToscaDataMap = validateRes.left().value();
+            result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, mergedToscaDataMap);
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
 
-		return updateOrAddToscaData(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField, false);
-	}
+    }
 
-	/**
-	 * Updates list of tosca data elements belonging to tosca element according received labels
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param toscaDataList
-	 * @param mapKeyField
-	 * @return
-	 */
-	public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, JsonPresentationFields mapKeyField) {
+    @SuppressWarnings("unchecked")
+    public <T extends ToscaDataDefinition> StorageOperationStatus updateFullToscaData(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, Map<String, T> toscaData) {
+        StorageOperationStatus result = null;
+        GraphVertex toscaDataVertex = null;
+        Map<String, T> existingToscaDataMap = null;
 
-		return updateOrAddToscaData(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField, true);
-	}
+        Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
+        if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != TitanOperationStatus.NOT_FOUND) {
+            TitanOperationStatus status = toscaDataVertexRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS, toscaElement.getUniqueId(), edgeLabel, status);
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
+        }
+        if (result == null) {
+            if (toscaDataVertexRes.isLeft()) {
+                toscaDataVertex = toscaDataVertexRes.left().value();
+                existingToscaDataMap = (Map<String, T>) toscaDataVertex.getJson();
+            }
 
-	@SuppressWarnings("unchecked")
-	private <T extends ToscaDataDefinition> StorageOperationStatus updateOrAddToscaData(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<T> toscaDataList, JsonPresentationFields mapKeyField, boolean isUpdate) {
-		StorageOperationStatus result = null;
-		GraphVertex toscaDataVertex = null;
-		Map<String, T> existingToscaDataMap = null;
-		Either<Map<String, T>, StorageOperationStatus> validateRes = null;
-		Map<String, T> mergedToscaDataMap;
-		Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
-		if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != TitanOperationStatus.NOT_FOUND) {
-			TitanOperationStatus status = toscaDataVertexRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get child vertex of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, status);
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
-		}
-		if (result == null) {
-			if (toscaDataVertexRes.isLeft()) {
-				toscaDataVertex = toscaDataVertexRes.left().value();
-				existingToscaDataMap = (Map<String, T>) toscaDataVertex.getJson();
-			}
 
- 			validateRes = validateMergeToscaData(toscaElement, toscaDataList, mapKeyField, existingToscaDataMap, isUpdate);
-			if (validateRes.isRight()) {
-				result = validateRes.right().value();
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed validate tosca data upon adding to tosca element {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, result);
-			}
-		}
-		if (result == null) {
-			mergedToscaDataMap = validateRes.left().value();
-			result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, mergedToscaDataMap);
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
+        }
+        if (result == null) {
 
-	}
-	
-	@SuppressWarnings("unchecked")
-	public <T extends ToscaDataDefinition> StorageOperationStatus updateFullToscaData(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, Map<String, T> toscaData) {
-		StorageOperationStatus result = null;
-		GraphVertex toscaDataVertex = null;
-		Map<String, T> existingToscaDataMap = null;		
-		
-		Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
-		if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != TitanOperationStatus.NOT_FOUND) {
-			TitanOperationStatus status = toscaDataVertexRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get child vertex of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, status);
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
-		}
-		if (result == null) {
-			if (toscaDataVertexRes.isLeft()) {
-				toscaDataVertex = toscaDataVertexRes.left().value();
-				existingToscaDataMap = (Map<String, T>) toscaDataVertex.getJson();
-			}
+            result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, toscaData);
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
 
-		
-		}
-		if (result == null) {
-			
-			result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, toscaData);
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
+    }
 
-	}
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private <T, K extends ToscaDataDefinition> StorageOperationStatus updateOrAddToscaDataDeepElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<K> toscaDataList, List<String> pathKeys,
+            JsonPresentationFields mapKeyField, boolean isUpdate) {
 
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	private <T, K extends ToscaDataDefinition> StorageOperationStatus updateOrAddToscaDataDeepElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<K> toscaDataList, List<String> pathKeys,
-			JsonPresentationFields mapKeyField, boolean isUpdate) {
+        StorageOperationStatus result = null;
+        GraphVertex toscaDataVertex = null;
+        Map<String, K> existingDeepElementsMap = null;
+        Either<Map<String, K>, StorageOperationStatus> validateRes = null;
+        Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
+        if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != TitanOperationStatus.NOT_FOUND) {
+            TitanOperationStatus status = toscaDataVertexRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS, toscaElement.getUniqueId(), edgeLabel, status);
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
+        }
+        if (result == null) {
+            if (toscaDataVertexRes.isLeft()) {
+                toscaDataVertex = toscaDataVertexRes.left().value();
+                existingDeepElementsMap = getDeepElements(toscaDataVertex, pathKeys);
+            }
+            validateRes = validateMergeToscaData(toscaElement, toscaDataList, mapKeyField, existingDeepElementsMap, isUpdate);
+            if (validateRes.isRight()) {
+                result = validateRes.right().value();
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed validate tosca data upon adding to tosca element {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, result);
+            }
+        }
+        if (result == null) {
+            updateDeepElements(toscaDataVertex, validateRes.left().value(), pathKeys);
+            Map<String, K> toscaDataToHandle;
+            if(toscaDataVertex == null){
+                toscaDataToHandle = new HashMap<>();
+                Map<String, K> currMap = toscaDataToHandle;
+                for (int i = 1; i < pathKeys.size()-1; ++i) {
+                    currMap.put(pathKeys.get(i), (K) new MapDataDefinition());
+                    currMap = (Map<String, K>) ((MapDataDefinition) currMap).getMapToscaDataDefinition().get(pathKeys.get(i));
+                }
+                toscaDataToHandle.put(pathKeys.get(pathKeys.size()-1), (K) new MapDataDefinition(validateRes.left().value()));
 
-		StorageOperationStatus result = null;
-		GraphVertex toscaDataVertex = null;
-		Map<String, K> existingDeepElementsMap = null;
-		Either<Map<String, K>, StorageOperationStatus> validateRes = null;
-		Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
-		if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != TitanOperationStatus.NOT_FOUND) {
-			TitanOperationStatus status = toscaDataVertexRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get child vertex of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, status);
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
-		}
-		if (result == null) {
-			if (toscaDataVertexRes.isLeft()) {
-				toscaDataVertex = toscaDataVertexRes.left().value();
-				existingDeepElementsMap = getDeepElements(toscaDataVertex, pathKeys);
-			}
-			validateRes = validateMergeToscaData(toscaElement, toscaDataList, mapKeyField, existingDeepElementsMap, isUpdate);
-			if (validateRes.isRight()) {
-				result = validateRes.right().value();
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed validate tosca data upon adding to tosca element {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, result);
-			}
-		}
-		if (result == null) {
-			updateDeepElements(toscaDataVertex, validateRes.left().value(), pathKeys);
-			Map<String, K> toscaDataToHandle;
-			if(toscaDataVertex == null){
-				toscaDataToHandle = new HashMap<>();
-				Map<String, K> currMap = toscaDataToHandle;
-				for (int i = 1; i < pathKeys.size()-1; ++i) {
-					currMap.put(pathKeys.get(i), (K) new MapDataDefinition());
-					currMap = (Map<String, K>) ((MapDataDefinition) currMap).getMapToscaDataDefinition().get(pathKeys.get(i));
-				}
-				toscaDataToHandle.put(pathKeys.get(pathKeys.size()-1), (K) new MapDataDefinition(validateRes.left().value()));
-				
-			} else {
-				toscaDataToHandle =  (Map<String, K>) toscaDataVertex.getJson();
-			}
-			result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, toscaDataToHandle);
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+            } else {
+                toscaDataToHandle =  (Map<String, K>) toscaDataVertex.getJson();
+            }
+            result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, toscaDataToHandle);
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	private <T, K extends ToscaDataDefinition> void updateDeepElements(GraphVertex toscaDataVertex, Map<String, K> mergedDeepElementMap, List<String> pathKeys) {
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private <T, K extends ToscaDataDefinition> void updateDeepElements(GraphVertex toscaDataVertex, Map<String, K> mergedDeepElementMap, List<String> pathKeys) {
 
-		if (toscaDataVertex != null && MapUtils.isNotEmpty(mergedDeepElementMap)) {
-			Map<String, MapDataDefinition> currMap = (Map<String, MapDataDefinition>) toscaDataVertex.getJson();
-			if(!currMap.containsKey(pathKeys.get(0))){
-				currMap.put(pathKeys.get(0), new MapDataDefinition<>());
-			}
-			MapDataDefinition currDeepElement = currMap.get(pathKeys.get(0));
+        if (toscaDataVertex != null && MapUtils.isNotEmpty(mergedDeepElementMap)) {
+            Map<String, MapDataDefinition> currMap = (Map<String, MapDataDefinition>) toscaDataVertex.getJson();
+            if(!currMap.containsKey(pathKeys.get(0))){
+                currMap.put(pathKeys.get(0), new MapDataDefinition<>());
+            }
+            MapDataDefinition currDeepElement = currMap.get(pathKeys.get(0));
 
-			for (int i = 1; i < pathKeys.size(); ++i) {
-				if(currDeepElement.findByKey(pathKeys.get(i)) == null){
-					currDeepElement.put(pathKeys.get(i), new MapDataDefinition<>());
-				}
-				currDeepElement = (MapDataDefinition) currDeepElement.findByKey(pathKeys.get(i));
-			}
-			if(currDeepElement != null){
-				for (Map.Entry<String, K> elementEntry : mergedDeepElementMap.entrySet()) {
-					currDeepElement.put(elementEntry.getKey(), elementEntry.getValue());
-				}
-			}
-		}
-	}
+            for (int i = 1; i < pathKeys.size(); ++i) {
+                if(currDeepElement.findByKey(pathKeys.get(i)) == null){
+                    currDeepElement.put(pathKeys.get(i), new MapDataDefinition<>());
+                }
+                currDeepElement = (MapDataDefinition) currDeepElement.findByKey(pathKeys.get(i));
+            }
+            if(currDeepElement != null){
+                for (Map.Entry<String, K> elementEntry : mergedDeepElementMap.entrySet()) {
+                    currDeepElement.put(elementEntry.getKey(), elementEntry.getValue());
+                }
+            }
+        }
+    }
 
-	@SuppressWarnings({ "unchecked", "rawtypes" })
-	private <T, K extends ToscaDataDefinition> Map<String, K> getDeepElements(GraphVertex toscaDataVertex, List<String> pathKeys) {
-		Map<String, K> result = null;
-		Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
-		MapDataDefinition currDeepElement = (MapDataDefinition) currMap.get(pathKeys.get(0));
-		for (int i = 1; i < pathKeys.size(); ++i) {
-			currDeepElement = (MapDataDefinition) currDeepElement.findByKey(pathKeys.get(i));
-		}
-		if(currDeepElement != null){
-			result = (Map<String, K>) currDeepElement.getMapToscaDataDefinition();
-		}
-		return result;
-	}
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private <T, K extends ToscaDataDefinition> Map<String, K> getDeepElements(GraphVertex toscaDataVertex, List<String> pathKeys) {
+        Map<String, K> result = null;
+        Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
+        MapDataDefinition currDeepElement = (MapDataDefinition) currMap.get(pathKeys.get(0));
+        for (int i = 1; i < pathKeys.size(); ++i) {
+            currDeepElement = (MapDataDefinition) currDeepElement.findByKey(pathKeys.get(i));
+        }
+        if(currDeepElement != null){
+            result = (Map<String, K>) currDeepElement.getMapToscaDataDefinition();
+        }
+        return result;
+    }
 
-	@SuppressWarnings("unchecked")
-	private <T extends ToscaDataDefinition> StorageOperationStatus addDeepElementsBlock(GraphVertex toscaDataVertex, T toscaDataBlock, String key) {
+    @SuppressWarnings("unchecked")
+    private <T extends ToscaDataDefinition> StorageOperationStatus addDeepElementsBlock(GraphVertex toscaDataVertex, T toscaDataBlock, String key) {
 
-		StorageOperationStatus result = null;
-		Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
-		if (currMap.containsKey(key)) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to add block of deep tosca data elements by label {}." + " The block element with the same key {} already exists. ", toscaDataVertex.getLabel(), key);
-			result = StorageOperationStatus.ENTITY_ALREADY_EXISTS;
-		}
-		if (result == null) {
-			currMap.put(key, toscaDataBlock);
-		}
-		return result;
-	}
+        StorageOperationStatus result = null;
+        Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
+        if (currMap.containsKey(key)) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add block of deep tosca data elements by label {}." + " The block element with the same key {} already exists. ", toscaDataVertex.getLabel(), key);
+            result = StorageOperationStatus.ENTITY_ALREADY_EXISTS;
+        }
+        if (result == null) {
+            currMap.put(key, toscaDataBlock);
+        }
+        return result;
+    }
 
-	@SuppressWarnings("unchecked")
-	private <T extends ToscaDataDefinition> StorageOperationStatus deleteDeepElementsBlock(GraphVertex toscaDataVertex, String key) {
+    @SuppressWarnings("unchecked")
+    private <T extends ToscaDataDefinition> StorageOperationStatus deleteDeepElementsBlock(GraphVertex toscaDataVertex, String key) {
 
-		StorageOperationStatus result = null;
-		Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
-		if (!currMap.containsKey(key)) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete block of deep tosca data elements by label {}." + " The block element with the same key {} doesn't exist. ", toscaDataVertex.getLabel(), key);
-			result = StorageOperationStatus.NOT_FOUND;
-		}
-		if (result == null) {
-			currMap.remove(key);
-		}
-		return null;
-	}
+        StorageOperationStatus result = null;
+        Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
+        if (!currMap.containsKey(key)) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete block of deep tosca data elements by label {}." + " The block element with the same key {} doesn't exist. ", toscaDataVertex.getLabel(), key);
+            result = StorageOperationStatus.NOT_FOUND;
+        }
+        if (result == null) {
+            currMap.remove(key);
+        }
+        return null;
+    }
 
-	/**
-	 * Removes tosca data vertex belonging to tosca element specified by uid according label
-	 * 
-	 * @param toscaElementUid
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @return
-	 */
-	public StorageOperationStatus removeToscaData(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel) {
+    /**
+     * Removes tosca data vertex belonging to tosca element specified by uid according label
+     *
+     * @param toscaElementUid
+     * @param edgeLabel
+     * @param vertexLabel
+     * @return
+     */
+    public StorageOperationStatus removeToscaData(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel) {
 
-		StorageOperationStatus statusRes = StorageOperationStatus.OK;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+        StorageOperationStatus statusRes = StorageOperationStatus.OK;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", toscaElementUid, status);
-			statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (statusRes == StorageOperationStatus.OK) {
-			statusRes = removeToscaDataVertex(getToscaElementRes.left().value(), edgeLabel, vertexLabel);
-		}
-		return statusRes;
-	}
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (statusRes == StorageOperationStatus.OK) {
+            statusRes = removeToscaDataVertex(getToscaElementRes.left().value(), edgeLabel, vertexLabel);
+        }
+        return statusRes;
+    }
 
-	/**
-	 * Removes tosca data vertex belonging to tosca element according label
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @return
-	 */
-	public StorageOperationStatus removeToscaDataVertex(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel) {
-		StorageOperationStatus result = null;
-		GraphVertex toscaDataVertex = null;
-		Iterator<Edge> edges = null;
-		int edgeCounter = 0;
-		Edge edge = null;
-		Edge edgeToDelete = null;
-		Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
-		if (toscaDataVertexRes.isRight()) {
-			TitanOperationStatus status = toscaDataVertexRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed remove tosca data vertex of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, status);
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
-		}
-		if (result == null) {
-			toscaDataVertex = toscaDataVertexRes.left().value();
-			edges = toscaDataVertex.getVertex().edges(Direction.IN);
-			if (edges == null || !edges.hasNext()) {
-				result = StorageOperationStatus.NOT_FOUND;
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed remove tosca data vertex of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, result);
-			}
-		}
-		if (result == null) {
-			while (edges.hasNext()) {
-				++edgeCounter;
-				edge = edges.next();
-				if (edge.outVertex().id().equals(toscaElement.getVertex().id())) {
-					edgeToDelete = edge;
-					break;
-				}
-			}
-			if (edgeToDelete == null) {
-				result = StorageOperationStatus.NOT_FOUND;
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed remove tosca data vertex of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, result);
-			}
-		}
-		if (result == null) {
-			if (edgeCounter > 1) {
-				edgeToDelete.remove();
-			} else {
-				toscaDataVertex.getVertex().remove();
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+    /**
+     * Removes tosca data vertex belonging to tosca element according label
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @return
+     */
+    public StorageOperationStatus removeToscaDataVertex(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel) {
+        StorageOperationStatus result = null;
+        GraphVertex toscaDataVertex = null;
+        Iterator<Edge> edges = null;
+        int edgeCounter = 0;
+        Edge edge = null;
+        Edge edgeToDelete = null;
+        Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
+        if (toscaDataVertexRes.isRight()) {
+            TitanOperationStatus status = toscaDataVertexRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS, toscaElement.getUniqueId(), edgeLabel, status);
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
+        }
+        if (result == null) {
+            toscaDataVertex = toscaDataVertexRes.left().value();
+            edges = toscaDataVertex.getVertex().edges(Direction.IN);
+            if (edges == null || !edges.hasNext()) {
+                result = StorageOperationStatus.NOT_FOUND;
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS, toscaElement.getUniqueId(), edgeLabel, result);
+            }
+        }
+        if (result == null) {
+            if (edges!=null) {
+	        	while (edges.hasNext()) {
+	                ++edgeCounter;
+	                edge = edges.next();
+	                if (edge.outVertex().id().equals(toscaElement.getVertex().id())) {
+	                    edgeToDelete = edge;
+	                    break;
+	                }
+	            }
+            }
+            if (edgeToDelete == null) {
+                result = StorageOperationStatus.NOT_FOUND;
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS, toscaElement.getUniqueId(), edgeLabel, result);
+            }
+        }
+        if (result == null) {
+            if (edgeCounter > 1 && edgeToDelete!=null) {
+                edgeToDelete.remove();
+            } else {
+                toscaDataVertex.getVertex().remove();
+            }
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-	/**
-	 * Deletes tosca data elements belonging to tosca element specified by uid according label
-	 * 
-	 * @param toscaElementUid
-	 * @param edgeLabel
-	 * @param uniqueKeys
-	 * @return
-	 */
-	public StorageOperationStatus deleteToscaDataElements(String toscaElementUid, EdgeLabelEnum edgeLabel, List<String> uniqueKeys) {
+    /**
+     * Deletes tosca data elements belonging to tosca element specified by uid according label
+     *
+     * @param toscaElementUid
+     * @param edgeLabel
+     * @param uniqueKeys
+     * @return
+     */
+    public StorageOperationStatus deleteToscaDataElements(String toscaElementUid, EdgeLabelEnum edgeLabel, List<String> uniqueKeys) {
 
-		StorageOperationStatus statusRes = StorageOperationStatus.OK;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+        StorageOperationStatus statusRes = StorageOperationStatus.OK;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", toscaElementUid, status);
-			statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (statusRes == StorageOperationStatus.OK) {
-			statusRes = deleteToscaDataElements(getToscaElementRes.left().value(), edgeLabel, uniqueKeys);
-		}
-		return statusRes;
-	}
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (statusRes == StorageOperationStatus.OK) {
+            statusRes = deleteToscaDataElements(getToscaElementRes.left().value(), edgeLabel, uniqueKeys);
+        }
+        return statusRes;
+    }
 
-	/**
-	 * Deletes tosca data element belonging to tosca element specified by uid according label
-	 * 
-	 * @param toscaElementUid
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param uniqueKey
-	 * @param mapKeyField
-	 * @return
-	 */
-	public StorageOperationStatus deleteToscaDataElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String uniqueKey, JsonPresentationFields mapKeyField) {
+    /**
+     * Deletes tosca data element belonging to tosca element specified by uid according label
+     *
+     * @param toscaElementUid
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param uniqueKey
+     * @param mapKeyField
+     * @return
+     */
+    public StorageOperationStatus deleteToscaDataElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String uniqueKey, JsonPresentationFields mapKeyField) {
 
-		StorageOperationStatus statusRes = StorageOperationStatus.OK;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+        StorageOperationStatus statusRes = StorageOperationStatus.OK;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", toscaElementUid, status);
-			statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (statusRes == StorageOperationStatus.OK) {
-			statusRes = deleteToscaDataElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, uniqueKey, mapKeyField);
-		}
-		return statusRes;
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (statusRes == StorageOperationStatus.OK) {
+            statusRes = deleteToscaDataElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, uniqueKey, mapKeyField);
+        }
+        return statusRes;
 
-	}
+    }
 
-	/**
-	 * Deletes tosca data deep element belonging to tosca element specified by uid according label
-	 * 
-	 * @param toscaElementUid
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param uniqueKey
-	 * @param pathKeys
-	 * @param mapKeyField
-	 * @return
-	 */
-	public StorageOperationStatus deleteToscaDataDeepElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String uniqueKey, List<String> pathKeys, JsonPresentationFields mapKeyField) {
+    /**
+     * Deletes tosca data deep element belonging to tosca element specified by uid according label
+     *
+     * @param toscaElementUid
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param uniqueKey
+     * @param pathKeys
+     * @param mapKeyField
+     * @return
+     */
+    public StorageOperationStatus deleteToscaDataDeepElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String uniqueKey, List<String> pathKeys, JsonPresentationFields mapKeyField) {
 
-		StorageOperationStatus statusRes = StorageOperationStatus.OK;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+        StorageOperationStatus statusRes = StorageOperationStatus.OK;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
 
-		getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			TitanOperationStatus status = getToscaElementRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", toscaElementUid, status);
-			statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (statusRes == StorageOperationStatus.OK) {
-			statusRes = deleteToscaDataDeepElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, uniqueKey, pathKeys, mapKeyField);
-		}
-		return statusRes;
+        getToscaElementRes = titanDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (statusRes == StorageOperationStatus.OK) {
+            statusRes = deleteToscaDataDeepElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, uniqueKey, pathKeys, mapKeyField);
+        }
+        return statusRes;
 
-	}
+    }
 
-	/**
-	 * Deletes tosca data deep element belonging to tosca element according label
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param uniqueKey
-	 * @param pathKeys
-	 * @param mapKeyField
-	 * @return
-	 */
-	public StorageOperationStatus deleteToscaDataDeepElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String uniqueKey, List<String> pathKeys, JsonPresentationFields mapKeyField) {
+    /**
+     * Deletes tosca data deep element belonging to tosca element according label
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param uniqueKey
+     * @param pathKeys
+     * @param mapKeyField
+     * @return
+     */
+    public StorageOperationStatus deleteToscaDataDeepElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String uniqueKey, List<String> pathKeys, JsonPresentationFields mapKeyField) {
 
-		List<String> uniqueKeys = new ArrayList<>();
-		uniqueKeys.add(uniqueKey);
-		return deleteToscaDataDeepElements(toscaElement, edgeLabel, vertexLabel, uniqueKeys, pathKeys, mapKeyField);
-	}
+        List<String> uniqueKeys = new ArrayList<>();
+        uniqueKeys.add(uniqueKey);
+        return deleteToscaDataDeepElements(toscaElement, edgeLabel, vertexLabel, uniqueKeys, pathKeys, mapKeyField);
+    }
 
-	public StorageOperationStatus deleteToscaDataDeepElements(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<String> uniqueKeys, List<String> pathKeys, JsonPresentationFields mapKeyField) {
+    public StorageOperationStatus deleteToscaDataDeepElements(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, List<String> uniqueKeys, List<String> pathKeys, JsonPresentationFields mapKeyField) {
 
-		StorageOperationStatus result = null;
-		GraphVertex toscaDataVertex;
-		Map<String, ToscaDataDefinition> existingToscaDataMap = null;
-		Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
-		if (toscaDataVertexRes.isRight()) {
-			TitanOperationStatus status = toscaDataVertexRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get child vertex of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, status);
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
-		}
-		if (result == null) {
-			toscaDataVertex = toscaDataVertexRes.left().value();
-			existingToscaDataMap = getDeepElements(toscaDataVertexRes.left().value(), pathKeys);
-			result = deleteElementsFromDataVertex(toscaElement, edgeLabel, uniqueKeys, toscaDataVertex, existingToscaDataMap);
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+        StorageOperationStatus result = null;
+        GraphVertex toscaDataVertex;
+        Map<String, ToscaDataDefinition> existingToscaDataMap = null;
+        Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
+        if (toscaDataVertexRes.isRight()) {
+            TitanOperationStatus status = toscaDataVertexRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS, toscaElement.getUniqueId(), edgeLabel, status);
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
+        }
+        if (result == null) {
+            toscaDataVertex = toscaDataVertexRes.left().value();
+            existingToscaDataMap = getDeepElements(toscaDataVertexRes.left().value(), pathKeys);
+            result = deleteElementsFromDataVertex(toscaElement, edgeLabel, uniqueKeys, toscaDataVertex, existingToscaDataMap);
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-	private StorageOperationStatus deleteElementsFromDataVertex(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, List<String> uniqueKeys, GraphVertex toscaDataVertex, Map<String, ToscaDataDefinition> existingToscaDataMap) {
-		StorageOperationStatus result;
-		for (String uniqueKey : uniqueKeys) {
-			result = removeKeyFromDataVertex(uniqueKey, existingToscaDataMap);
-			if (result != StorageOperationStatus.OK) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete tosca data element of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, result);
-				break;
-			}
-		}
-		result = updateToscaDataElement(toscaElement, edgeLabel, toscaDataVertex);
-		return result;
-	}
+    private StorageOperationStatus deleteElementsFromDataVertex(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, List<String> uniqueKeys, GraphVertex toscaDataVertex, Map<String, ToscaDataDefinition> existingToscaDataMap) {
+        StorageOperationStatus result;
+        for (String uniqueKey : uniqueKeys) {
+            result = removeKeyFromDataVertex(uniqueKey, existingToscaDataMap);
+            if (result != StorageOperationStatus.OK) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete tosca data element of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, result);
+                break;
+            }
+        }
+        result = updateToscaDataElement(toscaElement, edgeLabel, toscaDataVertex);
+        return result;
+    }
 
-	/**
-	 * Deletes tosca data element belonging to tosca element according label
-	 * 
-	 * @param toscaElement
-	 * @param edgeLabel
-	 * @param vertexLabel
-	 * @param uniqueKey
-	 * @param mapKeyField
-	 * @return
-	 */
-	public StorageOperationStatus deleteToscaDataElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String uniqueKey, JsonPresentationFields mapKeyField) {
+    /**
+     * Deletes tosca data element belonging to tosca element according label
+     *
+     * @param toscaElement
+     * @param edgeLabel
+     * @param vertexLabel
+     * @param uniqueKey
+     * @param mapKeyField
+     * @return
+     */
+    public StorageOperationStatus deleteToscaDataElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel, String uniqueKey, JsonPresentationFields mapKeyField) {
 
-		List<String> uniqueKeys = new ArrayList<>();
-		uniqueKeys.add(uniqueKey);
-		return deleteToscaDataElements(toscaElement, edgeLabel, uniqueKeys);
-	}
+        List<String> uniqueKeys = new ArrayList<>();
+        uniqueKeys.add(uniqueKey);
+        return deleteToscaDataElements(toscaElement, edgeLabel, uniqueKeys);
+    }
 
-	@SuppressWarnings("unchecked")
+    @SuppressWarnings("unchecked")
 /**
  * Deletes tosca data elements belonging to tosca element according label
  * @param toscaElement
@@ -1290,110 +1290,125 @@
  * @param uniqueKeys
  * @return
  */
-	public StorageOperationStatus deleteToscaDataElements(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, List<String> uniqueKeys) {
-		StorageOperationStatus result = null;
-		GraphVertex toscaDataVertex;
-		Map<String, ToscaDataDefinition> existingToscaDataMap;
-		Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
-		if (toscaDataVertexRes.isRight()) {
-			TitanOperationStatus status = toscaDataVertexRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get child vertex of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel, status);
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
-		}
-		if (result == null) {
-			toscaDataVertex = toscaDataVertexRes.left().value();
-			existingToscaDataMap = (Map<String, ToscaDataDefinition>) toscaDataVertex.getJson();
-			result = deleteElementsFromDataVertex(toscaElement, edgeLabel, uniqueKeys, toscaDataVertex, existingToscaDataMap);
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+    public StorageOperationStatus deleteToscaDataElements(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, List<String> uniqueKeys) {
+        StorageOperationStatus result = null;
+        GraphVertex toscaDataVertex;
+        Map<String, ToscaDataDefinition> existingToscaDataMap;
+        Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = titanDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
+        if (toscaDataVertexRes.isRight()) {
+            TitanOperationStatus status = toscaDataVertexRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS, toscaElement.getUniqueId(), edgeLabel, status);
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(toscaDataVertexRes.right().value());
+        }
+        if (result == null) {
+            toscaDataVertex = toscaDataVertexRes.left().value();
+            existingToscaDataMap = (Map<String, ToscaDataDefinition>) toscaDataVertex.getJson();
+            result = deleteElementsFromDataVertex(toscaElement, edgeLabel, uniqueKeys, toscaDataVertex, existingToscaDataMap);
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-	private <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, GraphVertex toscaDataVertex) {
-		StorageOperationStatus result = StorageOperationStatus.OK;
-		Either<GraphVertex, TitanOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
-		if (updateOrCopyRes.isRight()) {
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(updateOrCopyRes.right().value());
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update tosca data {} of the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), result);
-		}
-		return result;
-	}
+    /**
+     * Adds the map data entry to the graph vertex of the specified type, related with the specified edge to the component specified by ID
+     * @param componentId       The uniqueId of the component
+     * @param vertexTypeEnum    The type of the vertex
+     * @param edgeLabelEnum     The type of the edge
+     * @param mapDataEntry      The map data entry
+     * @param <T extends MapDataDefinition>
+     * @return                  The status of the operation result
+     */
+    public <T extends MapDataDefinition> StorageOperationStatus addElementToComponent(String componentId, VertexTypeEnum vertexTypeEnum, EdgeLabelEnum edgeLabelEnum, Map.Entry<String, T> mapDataEntry){
+        if(MapUtils.isNotEmpty(mapDataEntry.getValue().getMapToscaDataDefinition()))
+            return addToscaDataDeepElementsBlockToToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, mapDataEntry.getValue(), mapDataEntry.getKey());
+        return StorageOperationStatus.OK;
+    }
 
-	private <T extends ToscaDataDefinition> StorageOperationStatus removeKeyFromDataVertex(String uniqueKey, Map<String, T> existingToscaDataMap) {
-		if (!existingToscaDataMap.containsKey(uniqueKey)) {
-			return StorageOperationStatus.NOT_FOUND;
-		}
-		existingToscaDataMap.remove(uniqueKey);
-		return StorageOperationStatus.OK;
-	}
+    private <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, GraphVertex toscaDataVertex) {
+        StorageOperationStatus result = StorageOperationStatus.OK;
+        Either<GraphVertex, TitanOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
+        if (updateOrCopyRes.isRight()) {
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(updateOrCopyRes.right().value());
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update tosca data {} of the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), result);
+        }
+        return result;
+    }
 
-	protected <K extends ToscaDataDefinition> StorageOperationStatus handleToscaData(GraphVertex toscaElement, VertexTypeEnum vertexLabel, EdgeLabelEnum edgeLabel, GraphVertex toscaDataVertex, Map<String, K> mergedToscaDataMap) {
+    private <T extends ToscaDataDefinition> StorageOperationStatus removeKeyFromDataVertex(String uniqueKey, Map<String, T> existingToscaDataMap) {
+        if (!existingToscaDataMap.containsKey(uniqueKey)) {
+            return StorageOperationStatus.NOT_FOUND;
+        }
+        existingToscaDataMap.remove(uniqueKey);
+        return StorageOperationStatus.OK;
+    }
 
-		StorageOperationStatus result = StorageOperationStatus.OK;
-		if (toscaDataVertex == null) {
+    protected <K extends ToscaDataDefinition> StorageOperationStatus handleToscaData(GraphVertex toscaElement, VertexTypeEnum vertexLabel, EdgeLabelEnum edgeLabel, GraphVertex toscaDataVertex, Map<String, K> mergedToscaDataMap) {
 
-			Either<GraphVertex, StorageOperationStatus> createRes = assosiateElementToData(toscaElement, vertexLabel, edgeLabel, mergedToscaDataMap);
-			if (createRes.isRight()) {
-				StorageOperationStatus status = createRes.right().value();
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to assosiate tosca data {} of the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), status);
-				result = status;
-			}
-		} else {
-			toscaDataVertex.setJson(mergedToscaDataMap);
-			Either<GraphVertex, TitanOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
-			if (updateOrCopyRes.isRight()) {
-				TitanOperationStatus status = updateOrCopyRes.right().value();
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to add tosca data {} to the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), status);
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-			}
-		}
-		return result;
-	}
+        StorageOperationStatus result = StorageOperationStatus.OK;
+        if (toscaDataVertex == null) {
 
-	private <T extends ToscaDataDefinition> Either<Map<String, T>, StorageOperationStatus> validateMergeToscaData(GraphVertex toscaElement, List<T> toscaDataList, JsonPresentationFields mapKeyField, Map<String, T> existingToscaDataMap,
-			boolean isUpdate) {
+            Either<GraphVertex, StorageOperationStatus> createRes = associateElementToData(toscaElement, vertexLabel, edgeLabel, mergedToscaDataMap);
+            if (createRes.isRight()) {
+                StorageOperationStatus status = createRes.right().value();
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to assosiate tosca data {} of the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), status);
+                result = status;
+            }
+        } else {
+            toscaDataVertex.setJson(mergedToscaDataMap);
+            Either<GraphVertex, TitanOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
+            if (updateOrCopyRes.isRight()) {
+                TitanOperationStatus status = updateOrCopyRes.right().value();
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data {} to the tosca element {}. Status is {}. ", edgeLabel, toscaElement.getUniqueId(), status);
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+            }
+        }
+        return result;
+    }
 
-		Map<String, T> mergedToscaDataMap = new HashMap<>();
-		StorageOperationStatus status;
-		Either<Map<String, T>, StorageOperationStatus> result = Either.left(mergedToscaDataMap);
-		if (MapUtils.isNotEmpty(existingToscaDataMap)) {
-			mergedToscaDataMap.putAll(existingToscaDataMap);
-		}
-		for (T toscaDataElement : toscaDataList) {
-			status = handleToscaDataElement(toscaElement, mapKeyField, mergedToscaDataMap, toscaDataElement, isUpdate);
-			if (status != StorageOperationStatus.OK) {
-				result = Either.right(status);
-				break;
-			}
-		}
-		return result;
-	}
+    private <T extends ToscaDataDefinition> Either<Map<String, T>, StorageOperationStatus> validateMergeToscaData(GraphVertex toscaElement, List<T> toscaDataList, JsonPresentationFields mapKeyField, Map<String, T> existingToscaDataMap,
+            boolean isUpdate) {
 
-	private <T extends ToscaDataDefinition> StorageOperationStatus handleToscaDataElement(GraphVertex toscaElement, JsonPresentationFields mapKeyField, Map<String, T> mergedToscaDataMap, T toscaDataElement, boolean isUpdate) {
+        Map<String, T> mergedToscaDataMap = new HashMap<>();
+        StorageOperationStatus status;
+        Either<Map<String, T>, StorageOperationStatus> result = Either.left(mergedToscaDataMap);
+        if (MapUtils.isNotEmpty(existingToscaDataMap)) {
+            mergedToscaDataMap.putAll(existingToscaDataMap);
+        }
+        for (T toscaDataElement : toscaDataList) {
+            status = handleToscaDataElement(toscaElement, mapKeyField, mergedToscaDataMap, toscaDataElement, isUpdate);
+            if (status != StorageOperationStatus.OK) {
+                result = Either.right(status);
+                break;
+            }
+        }
+        return result;
+    }
 
-		StorageOperationStatus status = StorageOperationStatus.OK;
-		String currKey = (String) toscaDataElement.getToscaPresentationValue(mapKeyField);
-		if (StringUtils.isEmpty(currKey)) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to add tosca data to tosca element {}. The key is empty. ");
-			status = StorageOperationStatus.BAD_REQUEST;
-		} else if (!isUpdate && mergedToscaDataMap.containsKey(currKey)) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to add tosca data to tosca element {}. The element with the same key {} already exists. ", toscaElement.getUniqueId(), currKey);
-			status = StorageOperationStatus.BAD_REQUEST;
-		}
-		mergedToscaDataMap.put(currKey, toscaDataElement);
-		return status;
-	}
+    private <T extends ToscaDataDefinition> StorageOperationStatus handleToscaDataElement(GraphVertex toscaElement, JsonPresentationFields mapKeyField, Map<String, T> mergedToscaDataMap, T toscaDataElement, boolean isUpdate) {
 
-//	public StorageOperationStatus updateDataOnGraph(GraphVertex dataVertex) {
-//		Either<GraphVertex, TitanOperationStatus> updateVertex = titanDao.updateVertex(dataVertex);
-//		if (updateVertex.isRight()) {
-//			return DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertex.right().value());
-//		}
-//		return StorageOperationStatus.OK;
-//	}
-	
+        StorageOperationStatus status = StorageOperationStatus.OK;
+        String currKey = (String) toscaDataElement.getToscaPresentationValue(mapKeyField);
+        if (StringUtils.isEmpty(currKey)) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data to tosca element {}. The key is empty. ");
+            status = StorageOperationStatus.BAD_REQUEST;
+        } else if (!isUpdate && mergedToscaDataMap.containsKey(currKey)) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data to tosca element {}. The element with the same key {} already exists. ", toscaElement.getUniqueId(), currKey);
+            status = StorageOperationStatus.BAD_REQUEST;
+        }
+        mergedToscaDataMap.put(currKey, toscaDataElement);
+        return status;
+    }
+
+//    public StorageOperationStatus updateDataOnGraph(GraphVertex dataVertex) {
+//        Either<GraphVertex, TitanOperationStatus> updateVertex = titanDao.updateVertex(dataVertex);
+//        if (updateVertex.isRight()) {
+//            return DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertex.right().value());
+//        }
+//        return StorageOperationStatus.OK;
+//    }
+
     protected GroupInstanceDataDefinition buildGroupInstanceDataDefinition(GroupDataDefinition group, ComponentInstanceDataDefinition componentInstance, Map<String, ArtifactDataDefinition> instDeplArtifMap) {
 
         String componentInstanceName = componentInstance.getName();
@@ -1437,22 +1452,25 @@
         return groupInstance;
   }
 
-	
-	protected String buildGroupInstanceName(String instanceName, String groupName) {
-		return ValidationUtils.normalizeComponentInstanceName(instanceName) + ".." + groupName;
-	}
 
-	protected String generateCustomizationUUID() {
-		return UUID.randomUUID().toString();
-	}
-	
-	protected void convertPropertiesToInstanceProperties(List<PropertyDataDefinition> properties){
-		properties.forEach(p -> p.convertPropertyDataToInstancePropertyData());
-	}
+    protected String buildGroupInstanceName(String instanceName, String groupName) {
+        return ValidationUtils.normalizeComponentInstanceName(instanceName) + ".." + groupName;
+    }
 
-	private TitanOperationStatus logAndReturn(TitanOperationStatus titanOperationStatus, String logMsg, Object ... logParams) {
-		logger.debug(logMsg, logParams);
-		return titanOperationStatus;
-	}
+    protected String generateCustomizationUUID() {
+        return UUID.randomUUID().toString();
+    }
 
+    protected void convertPropertiesToInstanceProperties(List<PropertyDataDefinition> properties){
+        properties.forEach(PropertyDataDefinition::convertPropertyDataToInstancePropertyData);
+    }
+
+    private TitanOperationStatus logAndReturn(TitanOperationStatus titanOperationStatus, String logMsg, Object ... logParams) {
+        log.debug(logMsg, logParams);
+        return titanOperationStatus;
+    }
+
+    private GraphVertex throwStorageException(TitanOperationStatus status) {
+        throw new StorageException(status);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ByToscaNameDerivedNodeTypeResolver.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ByToscaNameDerivedNodeTypeResolver.java
index 5e5ee63..5748629 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ByToscaNameDerivedNodeTypeResolver.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ByToscaNameDerivedNodeTypeResolver.java
@@ -20,10 +20,7 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
@@ -35,7 +32,9 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import fj.data.Either;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Component("derived-resource-resolver")
 public class ByToscaNameDerivedNodeTypeResolver implements DerivedNodeTypeResolver {
@@ -45,7 +44,7 @@
 
     @Override
     public Either<List<GraphVertex>, TitanOperationStatus> findDerivedResources(String parentResource) {
-        Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
         propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
 
         propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, parentResource);
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CategoryOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CategoryOperation.java
index 5b70229..88f0ea3 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CategoryOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CategoryOperation.java
@@ -20,10 +20,7 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
@@ -33,61 +30,62 @@
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import fj.data.Either;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @org.springframework.stereotype.Component("category-operation")
 public class CategoryOperation extends BaseOperation{
-	
-	private static Logger log = LoggerFactory.getLogger(CategoryOperation.class.getName());
 
-	/** 
-	 * 
-	 * @param name
-	 * @param type
-	 * @return
-	 */
-	public  Either<GraphVertex, StorageOperationStatus> getCategory(String name, VertexTypeEnum type) {
-		if (name != null) {
-			String categoryUid = UniqueIdBuilder.buildComponentCategoryUid(name, type);
-			Map<GraphPropertyEnum, Object> props = new HashMap<>();
-			props.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(name));
-			Either<List<GraphVertex>, TitanOperationStatus> either = titanDao.getByCriteria(type, props);
+    private static final Logger log = Logger.getLogger(CategoryOperation.class.getName());
 
-			if (either.isRight()) {
-				TitanOperationStatus titanOperationStatus = either.right().value();
-				log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name());
-				if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
-					return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
-				} else {
-					return Either.right(StorageOperationStatus.GENERAL_ERROR);
-				}
-			}
-			return Either.left(either.left().value().get(0));
-		} else {
-			return Either.right(StorageOperationStatus.GENERAL_ERROR);
-		}
-	}
-	/** 
-	 * 
-	 * @param categoryV
-	 * @param name
-	 * @return
-	 */
-	public  Either<GraphVertex, StorageOperationStatus> getSubCategoryForCategory(GraphVertex categoryV, String name ) {
-		Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = titanDao.getChildrenVertecies(categoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
-		if ( childrenVertecies.isRight() ){
-			log.debug("Failed to fetch children verticies for category {} error {}", categoryV.getUniqueId(), childrenVertecies.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
-		}
-		for ( GraphVertex childV : childrenVertecies.left().value() ){
-			if ( childV.getMetadataProperty(GraphPropertyEnum.NAME).equals(name) ){
-				return Either.left(childV);
-			}
-		}
-		return Either.right(StorageOperationStatus.NOT_FOUND);
-	}
+    /**
+     *
+     * @param name
+     * @param type
+     * @return
+     */
+    public  Either<GraphVertex, StorageOperationStatus> getCategory(String name, VertexTypeEnum type) {
+        if (name != null) {
+            String categoryUid = UniqueIdBuilder.buildComponentCategoryUid(name, type);
+            Map<GraphPropertyEnum, Object> props = new HashMap<>();
+            props.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(name));
+            Either<List<GraphVertex>, TitanOperationStatus> either = titanDao.getByCriteria(type, props);
+
+            if (either.isRight()) {
+                TitanOperationStatus titanOperationStatus = either.right().value();
+                log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name());
+                if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
+                    return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
+                } else {
+                    return Either.right(StorageOperationStatus.GENERAL_ERROR);
+                }
+            }
+            return Either.left(either.left().value().get(0));
+        } else {
+            return Either.right(StorageOperationStatus.GENERAL_ERROR);
+        }
+    }
+    /**
+     *
+     * @param categoryV
+     * @param name
+     * @return
+     */
+    public  Either<GraphVertex, StorageOperationStatus> getSubCategoryForCategory(GraphVertex categoryV, String name ) {
+        Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = titanDao.getChildrenVertecies(categoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
+        if ( childrenVertecies.isRight() ){
+            log.debug("Failed to fetch children verticies for category {} error {}", categoryV.getUniqueId(), childrenVertecies.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
+        }
+        for ( GraphVertex childV : childrenVertecies.left().value() ){
+            if ( childV.getMetadataProperty(GraphPropertyEnum.NAME).equals(name) ){
+                return Either.left(childV);
+            }
+        }
+        return Either.right(StorageOperationStatus.NOT_FOUND);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ExternalReferencesOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ExternalReferencesOperation.java
index 2b35699..70cfc5d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ExternalReferencesOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ExternalReferencesOperation.java
@@ -1,11 +1,7 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
 
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
@@ -14,12 +10,13 @@
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.elements.MapComponentInstanceExternalRefs;
 import org.openecomp.sdc.be.model.jsontitan.utils.IdMapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.be.model.operations.impl.OperationUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import fj.data.Either;
+import java.util.*;
+
+import static java.util.Collections.emptyMap;
 
 /**
  * Created by yavivi on 26/01/2018.
@@ -27,18 +24,12 @@
 @Component
 public class ExternalReferencesOperation extends BaseOperation {
 
-    private static final Logger log = LoggerFactory.getLogger(ExternalReferencesOperation.class);
-
-    public IdMapper getIdMapper() {
-        return idMapper;
-    }
-
-    public void setIdMapper(IdMapper idMapper) {
-        this.idMapper = idMapper;
-    }
+    @Autowired
+    private IdMapper idMapper;
 
     @Autowired
-    protected IdMapper idMapper;
+    private OperationUtils operationUtils;
+
 
     /**
      * Constructor
@@ -51,27 +42,27 @@
     }
 
     public Either<String, ActionStatus> addExternalReferenceWithCommit(String serviceUuid, String componentInstanceName, String objectType, String reference) {
-        Either<String, ActionStatus> addResult = this.addExternalReference(serviceUuid, componentInstanceName, objectType, reference);
-        this.titanDao.commit();
+        Either<String, ActionStatus> addResult = addExternalReference(serviceUuid, componentInstanceName, objectType, reference);
+        titanDao.commit();
         return addResult;
     }
 
     public Either<String, ActionStatus> deleteExternalReferenceWithCommit(String serviceUuid, String componentInstanceName, String objectType, String reference) {
-        Either<String, ActionStatus> result = this.deleteExternalReference(serviceUuid, componentInstanceName, objectType, reference);
-        this.titanDao.commit();
+        Either<String, ActionStatus> result = deleteExternalReference(serviceUuid, componentInstanceName, objectType, reference);
+        titanDao.commit();
         return result;
     }
 
     public Either<String, ActionStatus> updateExternalReferenceWithCommit(String serviceVertexUuid, String componentInstanceName, String objectType, String oldRef, String newRef) {
-        Either<String, ActionStatus> updateResult = this.updateExternalReference(serviceVertexUuid, componentInstanceName, objectType, oldRef, newRef);
-        this.titanDao.commit();
+        Either<String, ActionStatus> updateResult = updateExternalReference(serviceVertexUuid, componentInstanceName, objectType, oldRef, newRef);
+        titanDao.commit();
         return updateResult;
     }
 
     public Either<String, ActionStatus> addExternalReference(String assetUuid, String componentInstanceName, String objectType, String reference) {
 
-        //Get Service vertex
-        Either<GraphVertex, TitanOperationStatus> vertexById = this.titanDao.getVertexById(assetUuid);
+        //Get Container vertex
+        Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(assetUuid);
         if (vertexById.isRight()){
             return Either.right(ActionStatus.RESOURCE_NOT_FOUND);
         }
@@ -84,37 +75,31 @@
         }
 
         //Get the external references map vertex
-        final Either<GraphVertex, TitanOperationStatus> dataVertexResult = this.getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
+        final Either<GraphVertex, TitanOperationStatus> dataVertexResult = getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
 
         //Check whether data vertex found
         GraphVertex externalRefsVertex = dataVertexResult.isLeft() ? dataVertexResult.left().value() : null;
 
         //instanceId -> externalRefsMap
-        Map<String, MapComponentInstanceExternalRefs> externalReferencesFullData = null;
+        Map<String, MapComponentInstanceExternalRefs> externalReferencesFullData;
         if (externalRefsVertex == null) {
-            //External Refs vertext does not exist, create its map.
-            externalReferencesFullData = new HashMap<String, MapComponentInstanceExternalRefs>() {
-                {
-                    MapComponentInstanceExternalRefs externalRefsMap = new MapComponentInstanceExternalRefs();
-                    put(compInstanceUniqueId, externalRefsMap);
-                }
-            };
+            //External Refs vertex does not exist, create its map.
+            externalReferencesFullData = new HashMap<>();
+            externalReferencesFullData.put(compInstanceUniqueId, new MapComponentInstanceExternalRefs());
         } else {
             externalReferencesFullData = (Map<String, MapComponentInstanceExternalRefs>) externalRefsVertex.getJson();
-            if (externalReferencesFullData.get(compInstanceUniqueId) == null){
-                externalReferencesFullData.put(compInstanceUniqueId, new MapComponentInstanceExternalRefs());
-            }
+            externalReferencesFullData.computeIfAbsent(compInstanceUniqueId, k -> new MapComponentInstanceExternalRefs());
         }
 
-        boolean isAdded = this.addExternalRef(externalReferencesFullData, compInstanceUniqueId, objectType, reference);
-        this.updateFullToscaData(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS, VertexTypeEnum.EXTERNAL_REF, externalReferencesFullData);
+        boolean isAdded = addExternalRef(externalReferencesFullData, compInstanceUniqueId, objectType, reference);
+        updateFullToscaData(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS, VertexTypeEnum.EXTERNAL_REF, externalReferencesFullData);
 
         return isAdded ? Either.left(reference) : Either.right(ActionStatus.EXT_REF_ALREADY_EXIST);
     }
 
     public Either<String, ActionStatus> deleteExternalReference(String assetUuid, String componentInstanceName, String objectType, String reference){
         //Get Service vertex
-        Either<GraphVertex, TitanOperationStatus> vertexById = this.titanDao.getVertexById(assetUuid);
+        Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(assetUuid);
         if (vertexById.isRight()){
             return Either.right(ActionStatus.RESOURCE_NOT_FOUND);
         }
@@ -126,7 +111,7 @@
         }
 
         //Get the external references map vertex
-        final Either<GraphVertex, TitanOperationStatus> dataVertexResult = this.getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
+        final Either<GraphVertex, TitanOperationStatus> dataVertexResult = getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
 
         //Check whether data vertex found
         GraphVertex externalRefsVertex = dataVertexResult.isLeft() ? dataVertexResult.left().value() : null;
@@ -134,8 +119,8 @@
         if (externalRefsVertex != null) {
             Map<String, MapComponentInstanceExternalRefs> externalReferencesFullData = (Map<String, MapComponentInstanceExternalRefs>) externalRefsVertex.getJson();
             if (externalReferencesFullData != null) {
-                refDeleted = this.deleteExternalRef(externalReferencesFullData, compInstanceUniqueId, objectType, reference);
-                this.updateFullToscaData(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS, VertexTypeEnum.EXTERNAL_REF, externalReferencesFullData); //@ TODO if ref deleted
+                refDeleted = deleteExternalRef(externalReferencesFullData, compInstanceUniqueId, objectType, reference);
+                updateFullToscaData(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS, VertexTypeEnum.EXTERNAL_REF, externalReferencesFullData);
             }
         }
 
@@ -148,7 +133,7 @@
 
     public Either<String, ActionStatus> updateExternalReference(String assetUuid, String componentInstanceName, String objectType, String oldRef, String newRef) {
         //Get Service vertex
-        Either<GraphVertex, TitanOperationStatus> vertexById = this.titanDao.getVertexById(assetUuid);
+        Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(assetUuid);
         if (vertexById.isRight()){
             return Either.right(ActionStatus.RESOURCE_NOT_FOUND);
         }
@@ -162,7 +147,7 @@
         }
 
         //Get the external references map vertex
-        final Either<GraphVertex, TitanOperationStatus> dataVertexResult = this.getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
+        final Either<GraphVertex, TitanOperationStatus> dataVertexResult = getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
 
         //Check whether data vertex found
         GraphVertex externalRefsVertex = dataVertexResult.isLeft() ? dataVertexResult.left().value() : null;
@@ -170,8 +155,8 @@
         if (externalRefsVertex != null) {
             Map<String, MapComponentInstanceExternalRefs> externalReferencesFullData = (Map<String, MapComponentInstanceExternalRefs>) externalRefsVertex.getJson();
             if (externalReferencesFullData != null) {
-                refReplaced = this.updateExternalRef(externalReferencesFullData, compInstanceUniqueId, objectType, oldRef, newRef);
-                this.updateFullToscaData(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS, VertexTypeEnum.EXTERNAL_REF, externalReferencesFullData);
+                refReplaced = updateExternalRef(externalReferencesFullData, compInstanceUniqueId, objectType, oldRef, newRef);
+                updateFullToscaData(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS, VertexTypeEnum.EXTERNAL_REF, externalReferencesFullData);
             }
         }
         if (refReplaced) {
@@ -183,7 +168,7 @@
 
     public Either<Map<String, List<String>>, ActionStatus> getExternalReferences(String assetUuid, String objectType) {
         //Get Service vertex
-        Either<GraphVertex, TitanOperationStatus> vertexById = this.titanDao.getVertexById(assetUuid);
+        Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(assetUuid);
         if (vertexById.isRight()){
             return Either.right(ActionStatus.RESOURCE_NOT_FOUND);
         }
@@ -193,7 +178,7 @@
         Map<String, List<String>> result = new HashMap();
 
         //Get the external references map vertex
-        final Either<GraphVertex, TitanOperationStatus> dataVertexResult = this.getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
+        final Either<GraphVertex, TitanOperationStatus> dataVertexResult = getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
         //Check whether data vertex found
         GraphVertex externalRefsVertex = dataVertexResult.isLeft() ? dataVertexResult.left().value() : null;
         if (externalRefsVertex != null) {
@@ -214,9 +199,47 @@
         return Either.left(new HashMap<>());
     }
 
+    public void addAllExternalReferences(String containerUniqueId,
+                                         String compInstanceUniqueId,
+                                         Map<String, List<String>> instanceExternalReferences) {
+
+        GraphVertex serviceVertex = titanDao.getVertexById(containerUniqueId)
+                .left()
+                .on(operationUtils::onTitanOperationFailure);
+        Either<GraphVertex, TitanOperationStatus> dataVertex = getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
+        Map<String, MapComponentInstanceExternalRefs> externalReferencesFullData;
+        if (dataVertex.isLeft()) {
+            externalReferencesFullData = (Map<String, MapComponentInstanceExternalRefs>) dataVertex.left().value().getJson();
+        } else {
+            externalReferencesFullData = new HashMap<>();
+        }
+        externalReferencesFullData.put(compInstanceUniqueId, new MapComponentInstanceExternalRefs(instanceExternalReferences));
+        updateFullToscaData(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS, VertexTypeEnum.EXTERNAL_REF, externalReferencesFullData);
+    }
+
+    public Map<String, List<String>> getAllExternalReferences(String containerUniqueId,
+                                                              String compInstanceUniqueId) {
+        GraphVertex serviceVertex = titanDao.getVertexById(containerUniqueId)
+            .left()
+            .on(operationUtils::onTitanOperationFailure);
+
+        Either<GraphVertex, TitanOperationStatus> dataVertex = getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
+        if (dataVertex.isRight()) {
+            return new HashMap<>();
+        }
+        GraphVertex externalRefsVertex = dataVertex.left().value();
+        Map<String, MapComponentInstanceExternalRefs> externalReferencesFullData = externalRefsVertex == null ? null : (Map<String, MapComponentInstanceExternalRefs>) externalRefsVertex.getJson();
+        if (externalReferencesFullData != null) {
+            return externalReferencesFullData
+                    .getOrDefault(compInstanceUniqueId, new MapComponentInstanceExternalRefs())
+                    .getComponentInstanceExternalRefs();
+        }
+        return emptyMap();
+    }
+
     public Either<List<String>, ActionStatus> getExternalReferences(String assetUuid, String componentInstanceName, String objectType) {
         //Get Service vertex
-        Either<GraphVertex, TitanOperationStatus> vertexById = this.titanDao.getVertexById(assetUuid);
+        Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(assetUuid);
         if (vertexById.isRight()){
             return Either.right(ActionStatus.RESOURCE_NOT_FOUND);
         }
@@ -228,14 +251,14 @@
         }
 
         //Get the external references map vertex
-        final Either<GraphVertex, TitanOperationStatus> dataVertexResult = this.getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
+        final Either<GraphVertex, TitanOperationStatus> dataVertexResult = getDataVertex(serviceVertex, EdgeLabelEnum.EXTERNAL_REFS);
 
         //Check whether data vertex found
         GraphVertex externalRefsVertex = dataVertexResult.isLeft() ? dataVertexResult.left().value() : null;
         if (externalRefsVertex != null) {
             Map<String, MapComponentInstanceExternalRefs> externalReferencesFullData = (Map<String, MapComponentInstanceExternalRefs>) externalRefsVertex.getJson();
             if (externalReferencesFullData != null) {
-                return Either.left(this.getExternalReferencesByObjectId(externalReferencesFullData, compInstanceUniqueId, objectType));
+                return Either.left(getExternalReferencesByObjectId(externalReferencesFullData, compInstanceUniqueId, objectType));
             }
         }
 
@@ -243,10 +266,18 @@
         return Either.left(new LinkedList());
     }
 
+    public IdMapper getIdMapper() {
+        return idMapper;
+    }
+
+    public void setIdMapper(IdMapper idMapper) {
+        this.idMapper = idMapper;
+    }
+
     private List<String> getExternalReferencesByObjectId(Map<String, MapComponentInstanceExternalRefs> externalReferencesFullData, String componentInstanceId, String objectType) {
         MapComponentInstanceExternalRefs externalRefsMap = externalReferencesFullData.get(componentInstanceId);
         List<String> externalRefsByObjectType = externalRefsMap.getExternalRefsByObjectType(objectType);
-        return externalRefsByObjectType != null ? externalRefsByObjectType : new LinkedList<String>();
+        return externalRefsByObjectType != null ? externalRefsByObjectType : new LinkedList<>();
     }
 
     private boolean updateExternalRef(Map<String, MapComponentInstanceExternalRefs> externalReferencesFullData, String componentInstanceId, String objectType, String oldRef, String newRef) {
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ForwardingPathOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ForwardingPathOperation.java
index ed06704..0d82b0f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ForwardingPathOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ForwardingPathOperation.java
@@ -20,12 +20,7 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
@@ -37,14 +32,13 @@
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
-import fj.data.Either;
+import java.util.*;
 
 @org.springframework.stereotype.Component("forwarding-paths-operations")
 public class ForwardingPathOperation extends BaseOperation {
-    private static Logger logger = LoggerFactory.getLogger(ForwardingPathOperation.class.getName());
+    private static final Logger log = Logger.getLogger(ForwardingPathOperation.class.getName());
 
 
     public Either<Set<String>, StorageOperationStatus> deleteForwardingPath(Service service, Set<String> forwardingPathsToDelete) {
@@ -89,7 +83,7 @@
         getToscaElementRes = titanDao.getVertexById(serviceId, JsonParseFlagEnum.NoParse);
         if (getToscaElementRes.isRight()) {
             TitanOperationStatus status = getToscaElementRes.right().value();
-            CommonUtility.addRecordToLog(logger, CommonUtility.LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", serviceId, status);
+            CommonUtility.addRecordToLog(log, CommonUtility.LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", serviceId, status);
             statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
             return Either.right(statusRes);
         }
@@ -100,7 +94,7 @@
         statusRes = performUpdateToscaAction(isUpdateAction, serviceVertex, Arrays.asList(currentPath), JsonPresentationFields.FORWARDING_PATH);
         {
             if (!statusRes.equals(StorageOperationStatus.OK)) {
-                logger.error("Failed to find the parent capability of capability type {}. status is {}", serviceId, statusRes);
+                log.error("Failed to find the parent capability of capability type {}. status is {}", serviceId, statusRes);
                 return Either.right(statusRes);
             }
             return Either.left(currentPath);
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/GroupsOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/GroupsOperation.java
index 668a6d9..b417f83 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/GroupsOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/GroupsOperation.java
@@ -7,9 +7,9 @@
  * 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.
@@ -20,288 +20,376 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
+import fj.data.Either;
+import org.apache.commons.collections.MapUtils;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.*;
+import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
+import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.GroupInstance;
-import org.openecomp.sdc.be.model.GroupInstanceProperty;
-import org.openecomp.sdc.be.model.GroupProperty;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
+import org.openecomp.sdc.be.model.operations.StorageException;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
-import fj.data.Either;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.stream.Collectors;
 
 @org.springframework.stereotype.Component("groups-operation")
 public class GroupsOperation extends BaseOperation {
 
-	private static final Logger log = LoggerFactory.getLogger(GroupsOperation.class);
+    private static final Logger log = Logger.getLogger(GroupsOperation.class.getName());
 
-	public Either<List<GroupDefinition>, StorageOperationStatus> createGroups(Component component, Map<String, GroupDataDefinition> groups) {
-
-		Either<List<GroupDefinition>, StorageOperationStatus> result = null;
-		Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
-		StorageOperationStatus status = null;
-
-		if (result == null) {
-			getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
-			if (getComponentVertex.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
-			}
+	public StorageOperationStatus deleteCalculatedCapabilitiesWithProperties(String componentId, List<GroupDefinition> groupDefinitions) {
+		Optional<StorageOperationStatus> error = groupDefinitions.stream().map(g->removeCalculatedCapabilityFromComponent(componentId, g.getUniqueId())).filter(status-> status!=StorageOperationStatus.OK).findFirst();
+		if(!error.isPresent()){
+			Map<String, MapCapabilityProperty> extractCapabilityPropertiesFromGroups = ModelConverter.extractCapabilityPropertiesFromGroups(groupDefinitions, false);
+			error = extractCapabilityPropertiesFromGroups.keySet().stream().map(k->removeCalculatedCapabilityPropertiesFromComponent(componentId, k)).filter(status-> status!=StorageOperationStatus.OK).findFirst();
 		}
-		if (result == null) {
-			status = topologyTemplateOperation.associateGroupsToComponent(getComponentVertex.left().value(), groups);
-			if (status != StorageOperationStatus.OK) {
-				result = Either.right(status);
-			}
+		if(error.isPresent()){
+			return error.get();
 		}
-		if (result == null) {
-			result = Either.left(ModelConverter.convertToGroupDefinitions(groups));
-		}
-		return result;
+		return StorageOperationStatus.OK;
 	}
-	
-	public Either<List<GroupDefinition>, StorageOperationStatus> addGroups(Component component, List<GroupDataDefinition> groups) {
-		Either<List<GroupDefinition>, StorageOperationStatus> result = null;
-		Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
-		StorageOperationStatus status = null;
 
-		if (result == null) {
-			getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
-			if (getComponentVertex.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
-			}
-		} 
-		if (result == null) {
-			status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.NAME);
-			
-			if (status != StorageOperationStatus.OK) {
-				result = Either.right(status);
-			}
-		}
-		
-		if (result == null) {
-			Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
-			result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
-		}
-		return result;
-	}
-	
-	public Either<List<GroupDefinition>, StorageOperationStatus> deleteGroups(Component component, List<GroupDataDefinition> groups) {
-		Either<List<GroupDefinition>, StorageOperationStatus> result = null;
-		Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
-		StorageOperationStatus status = null;
-
-		if (result == null) {
-			getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
-			if (getComponentVertex.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
-			}
-		} 
-		if (result == null) {
-			List<String> groupName = groups.stream().map(g -> g.getName()).collect(Collectors.toList());
-			status = deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.GROUPS, groupName);
-						
-			if (status != StorageOperationStatus.OK) {
-				result = Either.right(status);
-			}
-		}
-		
-		if (result == null) {
-			Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
-			result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
-		}
-		return result;
-	}
-	
-	public <T extends GroupDataDefinition> Either<List<GroupDefinition>, StorageOperationStatus> updateGroups(Component component, List<T> groups) {
-		Either<List<GroupDefinition>, StorageOperationStatus> result = null;
-		Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
-		StorageOperationStatus status = null;
-
-		if (result == null) {
-			getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
-			if (getComponentVertex.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
-			}
-		} 
-		if (result == null) {
-			groups.forEach(gr -> {
-				String version = gr.getVersion();
-				String newVersion = increaseMajorVersion(version);
-				gr.setVersion(newVersion);
-				String groupUUID = UniqueIdBuilder.generateUUID();
-				gr.setGroupUUID(groupUUID);
-			});
-
-			status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.NAME);
-						
-			if (status != StorageOperationStatus.OK) {
-				result = Either.right(status);
-			}
-		}
-		
-		if (result == null) {
-			Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
-			result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
-		}
-		return result;
-	}
-	
-	
-	public Either<List<GroupProperty>, StorageOperationStatus> updateGroupPropertiesOnComponent(String componentId, GroupDefinition group, List<GroupProperty> newGroupProperties) {
-		
-		Either<List<GroupProperty>,StorageOperationStatus> result = null;
-		Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
-		GraphVertex componentVertex = null;
-
-		if (result == null) {
-			getComponentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
-			if (getComponentVertex.isRight()) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
-			}
-		} 
-		if (result == null) {
-			componentVertex = getComponentVertex.left().value();
-			//update 
-			List<PropertyDataDefinition> properties = group.getProperties();
-			newGroupProperties.forEach(np -> {
-				Optional<PropertyDataDefinition> currentProp = properties.stream().filter(p -> p.getName().equals(np.getName())).findAny();
-				if (currentProp.isPresent()) {	
-					currentProp.get().setValue(np.getValue());
-				}
-			});
-			
-			StorageOperationStatus updateDataRes = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, group, JsonPresentationFields.NAME);
-			if ( updateDataRes != StorageOperationStatus.OK ){
-				log.debug("Failed to update properties for group {} error {}", group.getName(), updateDataRes);
-				result = Either.right(updateDataRes);
-			}
-		}
-		if (result == null) {
-			componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
-			Either<GraphVertex, TitanOperationStatus> updateRes = titanDao.updateVertex(componentVertex);
-			if (updateRes.isRight()) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the component {}. Status is {} ",  componentId, updateRes.right().value());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateRes.right().value()));
-			}
-		}
-		if (result == null) {
-			result = Either.left(newGroupProperties);
-		}
-		return result;
-	}
-	
 	/**
-	 * The version of the group is an integer. In order to support BC, we might get a version in a float format.
-	 * 
-	 * @param version
-	 * @return
+	 * Adds the map of the calculated capabilities and the map of the calculated capabilities properties the the component on the graph
+	 * @param 	componentId
+	 * @param 	calculatedCapabilities
+	 * @param 	calculatedCapabilitiesProperties
+	 * @return	status of the result the operation
 	 */
-	private String increaseMajorVersion(String version) {
+	public StorageOperationStatus addCalculatedCapabilitiesWithProperties(String componentId, Map<String, MapListCapabilityDataDefinition> calculatedCapabilities, Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties) {
 
-		String[] versionParts = version.split(ToscaElementLifecycleOperation.VERSION_DELIMETER_REGEXP);
-		Integer majorVersion = Integer.parseInt(versionParts[0]);
+		Optional<StorageOperationStatus> error = calculatedCapabilities.entrySet().stream().map(e-> addElementToComponent(componentId, VertexTypeEnum.CALCULATED_CAPABILITIES, EdgeLabelEnum.CALCULATED_CAPABILITIES, e)).filter(status-> status!=StorageOperationStatus.OK).findFirst();
+		if(!error.isPresent()){
+			error = calculatedCapabilitiesProperties.entrySet().stream().map(e->addCalculatedCapabilityPropertiesToComponent(componentId, e)).filter(status-> status!=StorageOperationStatus.OK).findFirst();
+		}
+		if(error.isPresent()){
+			return error.get();
+		}
+		return StorageOperationStatus.OK;
+	}
+	
+	public StorageOperationStatus updateCalculatedCapabilitiesWithProperties(String componentId, Map<String, MapListCapabilityDataDefinition> calculatedCapabilities, Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties) {
 
-		majorVersion++;
-
-		return String.valueOf(majorVersion);
-
+		Optional<StorageOperationStatus> error = calculatedCapabilities.entrySet().stream().map(e->updateCalculatedCapabilityOfComponent(componentId, e)).filter(status-> status!=StorageOperationStatus.OK).findFirst();
+		if(!error.isPresent()){
+			error = calculatedCapabilitiesProperties.entrySet().stream().map(e->updateCalculatedCapabilityPropertiesOnComponent(componentId, e)).filter(status-> status!=StorageOperationStatus.OK).findFirst();
+		}
+		if(error.isPresent()){
+			return error.get();
+		}
+		return StorageOperationStatus.OK;
 	}
 
-	public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstances(Component component, String instanceId, List<GroupInstance> updatedGroupInstances) {
+	private StorageOperationStatus updateCalculatedCapabilityOfComponent(String componentId, Entry<String, MapListCapabilityDataDefinition> capabilities){
+		if(MapUtils.isNotEmpty(capabilities.getValue().getMapToscaDataDefinition()))
+			return updateToscaDataDeepElementsBlockToToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAPABILITIES, capabilities.getValue(), capabilities.getKey());
+		return StorageOperationStatus.OK;
+	}
+	
+	private StorageOperationStatus addCalculatedCapabilityPropertiesToComponent(String componentId, Entry<String, MapCapabilityProperty> properties){
+		if(MapUtils.isNotEmpty(properties.getValue().getMapToscaDataDefinition()))
+			return addToscaDataDeepElementsBlockToToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, properties.getValue(), properties.getKey());
+		return StorageOperationStatus.OK;
+	}
+	
+	private StorageOperationStatus updateCalculatedCapabilityPropertiesOnComponent(String componentId, Entry<String, MapCapabilityProperty> properties){
+		if(MapUtils.isNotEmpty(properties.getValue().getMapToscaDataDefinition()))
+			return updateToscaDataDeepElementsBlockToToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, properties.getValue(), properties.getKey());
+		return StorageOperationStatus.OK;
+	}
+	
+	private StorageOperationStatus removeCalculatedCapabilityFromComponent(String componentId, String groupId){
+		return deleteToscaDataDeepElementsBlockOfToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, groupId);
+	}
+	
+	private StorageOperationStatus removeCalculatedCapabilityPropertiesFromComponent(String componentId, String groupId){
+		return deleteToscaDataDeepElementsBlockOfToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, groupId);
+	}
 
-		Either<List<GroupInstance>, StorageOperationStatus> result = null;
-		StorageOperationStatus status = null;
 
-		Either<GraphVertex, TitanOperationStatus> getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
+    public Either<List<GroupDefinition>, StorageOperationStatus> createGroups(Component component, Map<String, GroupDataDefinition> groups) {
+
+        Either<List<GroupDefinition>, StorageOperationStatus> result = null;
+        Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
+        StorageOperationStatus status = null;
+
+		getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
 		if (getComponentVertex.isRight()) {
 			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
 		}
-		if (result == null) {
-			List<String> pathKeys = new ArrayList<>();
-			pathKeys.add(instanceId);
-			status = updateToscaDataDeepElementsOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, updatedGroupInstances, pathKeys,  JsonPresentationFields.NAME);
-			if (status != StorageOperationStatus.OK) {
-				result = Either.right(status);
-			}
-		}
-		if (result == null) {
-			result = Either.left(updatedGroupInstances);
-		}
-		return result;
-	}
+        if (result == null) {
+            status = topologyTemplateOperation.associateGroupsToComponent(getComponentVertex.left().value(), groups);
+            if (status != StorageOperationStatus.OK) {
+                result = Either.right(status);
+            }
+        }
+        if (result == null) {
+            result = Either.left(ModelConverter.convertToGroupDefinitions(groups));
+        }
+        return result;
+    }
 
-	public Either<GroupDefinition, StorageOperationStatus> updateGroup(Component component, GroupDefinition currentGroup) {
-		StorageOperationStatus status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.NAME);
-		if(status != StorageOperationStatus.OK){
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
-			return Either.right(status);
-		}
-		return Either.left(currentGroup);
-	}
+    public <T extends GroupDataDefinition> Either<List<GroupDefinition>, StorageOperationStatus> addGroups(Component component, List<T> groups) {
+        Either<List<GroupDefinition>, StorageOperationStatus> result = null;
+        Either<GraphVertex, TitanOperationStatus> getComponentVertex;
+        StorageOperationStatus status;
 
-	public StorageOperationStatus deleteGroup(Component component, String currentGroupName) {
-		StorageOperationStatus status = deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroupName, JsonPresentationFields.NAME);
-		if(status != StorageOperationStatus.OK){
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete group {} of component {}. The status is}. ", currentGroupName, component.getName(), status);
+		getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
+		if (getComponentVertex.isRight()) {
+			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
 		}
-		return status;
-	}
+        if (result == null) {
+            status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.NAME);
 
-	public Either<GroupDefinition, StorageOperationStatus> addGroup(Component component, GroupDefinition currentGroup) {
-		StorageOperationStatus status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.NAME);
-		if(status != StorageOperationStatus.OK){
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
-			return Either.right(status);
+            if (status != StorageOperationStatus.OK) {
+                result = Either.right(status);
+            }
+        }
+
+        if (result == null) {
+			Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap(GroupDataDefinition::getName, x->x));
+            result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
+        }
+        return result;
+    }
+
+    public Either<List<GroupDefinition>, StorageOperationStatus> deleteGroups(Component component, List<GroupDataDefinition> groups) {
+        Either<List<GroupDefinition>, StorageOperationStatus> result = null;
+        Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
+        StorageOperationStatus status = null;
+
+		getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
+		if (getComponentVertex.isRight()) {
+			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
 		}
-		return Either.left(currentGroup);
-	}
-	
-	public Either<GroupInstance, StorageOperationStatus> updateGroupInstancePropertyValuesOnGraph(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
+        if (result == null) {
+			List<String> groupName = groups.stream().map(GroupDataDefinition::getName).collect(Collectors.toList());
+            status = deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.GROUPS, groupName);
 
-		Either<GraphVertex, TitanOperationStatus> getComponentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
+            if (status != StorageOperationStatus.OK) {
+                result = Either.right(status);
+            }
+        }
+
+        if (result == null) {
+			Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( GroupDataDefinition::getName, x->x));
+            result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
+        }
+        return result;
+    }
+
+    public <T extends GroupDataDefinition> Either<List<GroupDefinition>, StorageOperationStatus> updateGroups(Component component, List<T> groups, boolean promoteVersion) {
+        Either<List<GroupDefinition>, StorageOperationStatus> result = null;
+        Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
+        StorageOperationStatus status = null;
+
+		getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
+		if (getComponentVertex.isRight()) {
+			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
+		}
+        if (result == null) {
+            groups.forEach(gr -> {
+                updateVersion(promoteVersion, gr);
+                String groupUUID = UniqueIdBuilder.generateUUID();
+                gr.setGroupUUID(groupUUID);
+            });
+
+            status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.NAME);
+
+            if (status != StorageOperationStatus.OK) {
+                result = Either.right(status);
+            }
+        }
+
+        if (result == null) {
+			Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( GroupDataDefinition::getName, x->x));
+            result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
+        }
+        return result;
+    }
+
+    private <T extends GroupDataDefinition> void updateVersion(boolean promoteVersion, T group) {
+        if(promoteVersion) {
+            String version = group.getVersion();
+            String newVersion = increaseMajorVersion(version);
+            group.setVersion(newVersion);
+        }
+    }
+
+    public void updateGroupOnComponent(String componentId, GroupDefinition groupDefinition) {
+        GraphVertex componentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata)
+                .left()
+                .on(this::onTitanError);
+
+        StorageOperationStatus updateToscaResult = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groupDefinition,
+                JsonPresentationFields.NAME);
+
+        if (StorageOperationStatus.OK != updateToscaResult) {
+            throw new StorageException(updateToscaResult, groupDefinition.getUniqueId());
+        }
+
+        updateLastUpdateDate(componentVertex);
+    }
+
+    private void updateLastUpdateDate(GraphVertex componentVertex) {
+        componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+        titanDao.updateVertex(componentVertex)
+                .left()
+                .on(this::onTitanError);
+    }
+
+    GraphVertex onTitanError(TitanOperationStatus titanOperationStatus) {
+        throw new StorageException(
+                DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus));
+    }
+
+    public Either<List<GroupProperty>, StorageOperationStatus> updateGroupPropertiesOnComponent(String componentId, GroupDefinition group, List<GroupProperty> newGroupProperties) {
+
+        Either<List<GroupProperty>, StorageOperationStatus> result = null;
+        Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
+        GraphVertex componentVertex = null;
+
+		getComponentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
 		if (getComponentVertex.isRight()) {
 			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
+			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
 		}
+        if (result == null) {
+            componentVertex = getComponentVertex.left().value();
+            //update
+            List<PropertyDataDefinition> properties = group.getProperties();
+            newGroupProperties.forEach(np -> {
+                Optional<PropertyDataDefinition> currentProp = properties.stream().filter(p -> p.getName().equals(np.getName())).findAny();
+                if (currentProp.isPresent()) {
+                    currentProp.get().setValue(np.getValue());
+                }
+            });
 
-		List<PropertyDataDefinition> propertiesOld = oldGroupInstance.getProperties();
-		newProperties.forEach(np -> {
-			Optional<PropertyDataDefinition> prop = propertiesOld.stream().filter(p -> p.getName().equals(np.getName())).findFirst();
-			if (prop.isPresent()) {
-				prop.get().setValue(np.getValue());
-			}
-		});
-		GroupInstanceDataDefinition groupInstanceDataDefinition = new GroupInstanceDataDefinition(oldGroupInstance);
-		List<String> pathKeys = new ArrayList<>();
-		pathKeys.add(instanceId);
-		StorageOperationStatus updateDataRes = updateToscaDataDeepElementOfToscaElement(componentId, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, groupInstanceDataDefinition, pathKeys, JsonPresentationFields.NAME);
-		if (updateDataRes != StorageOperationStatus.OK) {
-			log.debug("Failed to update properties for group instance {} error {}", oldGroupInstance.getName(), updateDataRes);
-			return Either.right(updateDataRes);
-		}
-		return Either.left(oldGroupInstance);
-	}
+            StorageOperationStatus updateDataRes = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, group, JsonPresentationFields.NAME);
+            if (updateDataRes != StorageOperationStatus.OK) {
+                log.debug("Failed to update properties for group {} error {}", group.getName(), updateDataRes);
+                result = Either.right(updateDataRes);
+            }
+        }
+        if (result == null) {
+            componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+            Either<GraphVertex, TitanOperationStatus> updateRes = titanDao.updateVertex(componentVertex);
+            if (updateRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the component {}. Status is {} ", componentId, updateRes.right().value());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateRes.right().value()));
+            }
+        }
+        if (result == null) {
+            result = Either.left(newGroupProperties);
+        }
+        return result;
+    }
 
+    /**
+     * The version of the group is an integer. In order to support BC, we might get a version in a float format.
+     *
+     * @param version
+     * @return
+     */
+    private String increaseMajorVersion(String version) {
+
+        String[] versionParts = version.split(ToscaElementLifecycleOperation.VERSION_DELIMITER_REGEXP);
+        Integer majorVersion = Integer.parseInt(versionParts[0]);
+
+        majorVersion++;
+
+        return String.valueOf(majorVersion);
+
+    }
+
+    public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstances(Component component, String instanceId, List<GroupInstance> updatedGroupInstances) {
+
+        Either<List<GroupInstance>, StorageOperationStatus> result = null;
+        StorageOperationStatus status = null;
+
+        Either<GraphVertex, TitanOperationStatus> getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
+        if (getComponentVertex.isRight()) {
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
+        }
+        if (result == null) {
+            List<String> pathKeys = new ArrayList<>();
+            pathKeys.add(instanceId);
+            status = updateToscaDataDeepElementsOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, updatedGroupInstances, pathKeys, JsonPresentationFields.NAME);
+            if (status != StorageOperationStatus.OK) {
+                result = Either.right(status);
+            }
+        }
+        if (result == null) {
+            result = Either.left(updatedGroupInstances);
+        }
+        return result;
+    }
+
+    public Either<GroupDefinition, StorageOperationStatus> updateGroup(Component component, GroupDefinition currentGroup) {
+        StorageOperationStatus status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.NAME);
+        if (status != StorageOperationStatus.OK) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
+            return Either.right(status);
+        }
+        return Either.left(currentGroup);
+    }
+
+    public StorageOperationStatus deleteGroup(Component component, String currentGroupName) {
+        StorageOperationStatus status = deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroupName, JsonPresentationFields.NAME);
+        if (status != StorageOperationStatus.OK) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete group {} of component {}. The status is}. ", currentGroupName, component.getName(), status);
+        }
+        return status;
+    }
+
+    public Either<GroupDefinition, StorageOperationStatus> addGroup(Component component, GroupDefinition currentGroup) {
+        StorageOperationStatus status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.NAME);
+        if (status != StorageOperationStatus.OK) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
+            return Either.right(status);
+        }
+        return Either.left(currentGroup);
+    }
+
+    public Either<GroupInstance, StorageOperationStatus> updateGroupInstancePropertyValuesOnGraph(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
+
+        Either<GraphVertex, TitanOperationStatus> getComponentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
+        if (getComponentVertex.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
+        }
+
+        List<PropertyDataDefinition> propertiesOld = oldGroupInstance.getProperties();
+        newProperties.forEach(np -> {
+            Optional<PropertyDataDefinition> prop = propertiesOld.stream().filter(p -> p.getName().equals(np.getName())).findFirst();
+            if (prop.isPresent()) {
+                prop.get().setValue(np.getValue());
+            }
+        });
+        GroupInstanceDataDefinition groupInstanceDataDefinition = new GroupInstanceDataDefinition(oldGroupInstance);
+        List<String> pathKeys = new ArrayList<>();
+        pathKeys.add(instanceId);
+        StorageOperationStatus updateDataRes = updateToscaDataDeepElementOfToscaElement(componentId, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, groupInstanceDataDefinition, pathKeys, JsonPresentationFields.NAME);
+        if (updateDataRes != StorageOperationStatus.OK) {
+            log.debug("Failed to update properties for group instance {} error {}", oldGroupInstance.getName(), updateDataRes);
+            return Either.right(updateDataRes);
+        }
+        return Either.left(oldGroupInstance);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfaceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfaceOperation.java
index ea2f8bc..a7587ad 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfaceOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfaceOperation.java
@@ -16,12 +16,7 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
@@ -33,15 +28,14 @@
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
-import fj.data.Either;
+import java.util.*;
 
 @org.springframework.stereotype.Component("interfaces-operation")
 public class InterfaceOperation extends BaseOperation {
 
-    private static Logger logger = LoggerFactory.getLogger(InterfaceOperation.class.getName());
+    private static final Logger logger = Logger.getLogger(InterfaceOperation.class.getName());
 
 
     public Either<Set<String>, StorageOperationStatus> deleteInterface(Resource resource,
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperation.java
index 561a95b..eb41232 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperation.java
@@ -20,71 +20,33 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Set;
-import java.util.UUID;
-import java.util.function.BiConsumer;
-import java.util.function.BiPredicate;
-import java.util.stream.Collectors;
-
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
-import org.openecomp.sdc.be.datatypes.elements.MapDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListCapabiltyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.*;
+import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
+import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-import org.openecomp.sdc.be.model.CapabilityDefinition;
-import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceInput;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.ComponentParametersView;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.GroupInstance;
-import org.openecomp.sdc.be.model.RelationshipImpl;
-import org.openecomp.sdc.be.model.RelationshipInfo;
-import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
-import org.openecomp.sdc.be.model.RequirementDefinition;
-import org.openecomp.sdc.be.model.Resource;
-import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
@@ -98,1905 +60,2111 @@
 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import fj.data.Either;
+import java.io.IOException;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.function.BiConsumer;
+import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
 
 @org.springframework.stereotype.Component("node-template-operation")
 public class NodeTemplateOperation extends BaseOperation {
+    private static final String FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR = "Failed to fetch container vertex {} error {}";
+	private static final String FAILED_TO_UPDATE_TOPOLOGY_TEMPLATE_WITH_NEW_COMPONENT_INSTANCE = "Failed to update topology template {} with new component instance {}. ";
 	private static final String ARTIFACT_PLACEHOLDER_TYPE = "type";
-	private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName";
-	private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description";
-	public static final String HEAT_ENV_NAME = "heatEnv";
-	public static final String HEAT_VF_ENV_NAME = "VfHeatEnv";
-	public static final String HEAT_ENV_SUFFIX = "env";
-	private static Integer defaultHeatTimeout;
-	public static final Integer NON_HEAT_TIMEOUT = 0;
+    private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName";
+    private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description";
+    public static final String HEAT_ENV_NAME = "heatEnv";
+    public static final String HEAT_VF_ENV_NAME = "VfHeatEnv";
+    public static final String HEAT_ENV_SUFFIX = "env";
+    private static Integer defaultHeatTimeout;
+    public static final Integer NON_HEAT_TIMEOUT = 0;
 
-	private static Logger logger = LoggerFactory.getLogger(NodeTemplateOperation.class.getName());
+    private static final Logger log = Logger.getLogger(NodeTemplateOperation.class.getName());
 
-	public NodeTemplateOperation() {
-		defaultHeatTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes();
-		if ((defaultHeatTimeout == null) || (defaultHeatTimeout < 1)) {
-			defaultHeatTimeout = 60;
-		}
-	}
+    public NodeTemplateOperation() {
+        defaultHeatTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes();
+        if ((defaultHeatTimeout == null) || (defaultHeatTimeout < 1)) {
+            defaultHeatTimeout = 60;
+        }
+    }
 
-	public static Integer getDefaultHeatTimeout() {
-		return defaultHeatTimeout;
-	}
+    public static Integer getDefaultHeatTimeout() {
+        return defaultHeatTimeout;
+    }
 
-	public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addComponentInstanceToTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, String instanceNumberSuffix, ComponentInstance componentInstance,
-			boolean allowDeleted, User user) {
+    public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addComponentInstanceToTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, String instanceNumberSuffix, ComponentInstance componentInstance,
+            boolean allowDeleted, User user) {
 
-		Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
-		Either<TopologyTemplate, StorageOperationStatus> addComponentInstanceRes = null;
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Going to create component instance {} in component {}", componentInstance, container.getUniqueId());
-		ComponentInstanceDataDefinition componentInstanceData = null;
-		Either<String, StorageOperationStatus> newInstanceNameRes = null;
+        Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
+        Either<TopologyTemplate, StorageOperationStatus> addComponentInstanceRes = null;
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Going to create component instance {} in component {}", componentInstance, container.getUniqueId());
+        ComponentInstanceDataDefinition componentInstanceData = null;
+        Either<String, StorageOperationStatus> newInstanceNameRes = null;
 
-		Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseJson);
-		if (metadataVertex.isRight()) {
-			TitanOperationStatus status = metadataVertex.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
+        Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseJson);
+        if (metadataVertex.isRight()) {
+            TitanOperationStatus status = metadataVertex.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
 
-		if (result == null) {
+        if (result == null) {
 
-			newInstanceNameRes = buildValidateInstanceName(container, originToscaElement, componentInstance, instanceNumberSuffix);
-			if (newInstanceNameRes.isRight()) {
-				result = Either.right(newInstanceNameRes.right().value());
-			}
-		}
-		if (result == null) {
-			componentInstanceData = buildComponentInstanceDataDefinition(componentInstance, container.getUniqueId(), newInstanceNameRes.left().value(), true, originToscaElement);
+            newInstanceNameRes = buildValidateInstanceName(container, originToscaElement, componentInstance, instanceNumberSuffix);
+            if (newInstanceNameRes.isRight()) {
+                result = Either.right(newInstanceNameRes.right().value());
+            }
+        }
+        if (result == null) {
+            componentInstanceData = buildComponentInstanceDataDefinition(componentInstance, container.getUniqueId(), newInstanceNameRes.left().value(), true, originToscaElement);
 
-			addComponentInstanceRes = addComponentInstanceToTopologyTemplate(container, originToscaElement, componentInstanceData, metadataVertex.left().value(), allowDeleted, user);
+            addComponentInstanceRes = addComponentInstanceToTopologyTemplate(container, originToscaElement, componentInstanceData, metadataVertex.left().value(), allowDeleted, user);
 
-			if (addComponentInstanceRes.isRight()) {
-				StorageOperationStatus status = addComponentInstanceRes.right().value();
-				if (status == StorageOperationStatus.NOT_FOUND) {
-					status = StorageOperationStatus.INVALID_ID;
-				}
-				result = Either.right(status);
-			}
-			if(componentInstance.getOriginType()  == OriginTypeEnum.ServiceProxy){
-				TopologyTemplate updatedContainer = addComponentInstanceRes.left().value();
-				result = addServerCapAndReqToProxyServerInstance(
-						updatedContainer, componentInstance, componentInstanceData);
-				
+            if (addComponentInstanceRes.isRight()) {
+                StorageOperationStatus status = addComponentInstanceRes.right().value();
+                if (status == StorageOperationStatus.NOT_FOUND) {
+                    status = StorageOperationStatus.INVALID_ID;
+                }
+                result = Either.right(status);
+            }
+            if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
+                TopologyTemplate updatedContainer = addComponentInstanceRes.left().value();
+                result = addServerCapAndReqToProxyServerInstance(updatedContainer, componentInstance, componentInstanceData);
 
-			
-			}
-		}
-		if (result == null) {
-			result = Either.left(new ImmutablePair<>(addComponentInstanceRes.left().value(), componentInstanceData.getUniqueId()));
-		}
-		return result;
-	}
+            }
+        }
+        if (result == null) {
+            result = Either.left(new ImmutablePair<>(addComponentInstanceRes.left().value(), componentInstanceData.getUniqueId()));
+        }
+        return result;
+    }
 
-	private Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addServerCapAndReqToProxyServerInstance(TopologyTemplate updatedContainer, ComponentInstance componentInstance,
-			
-			ComponentInstanceDataDefinition componentInstanceData) {
-		
-		Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result;
-		
-	
-		Map<String, MapListCapabiltyDataDefinition> calcCap = updatedContainer.getCalculatedCapabilities();
-		Map<String, MapListRequirementDataDefinition>  calcReg = updatedContainer.getCalculatedRequirements();
-		Map<String, MapCapabiltyProperty> calcCapProp = updatedContainer.getCalculatedCapabilitiesProperties();
-		
-		
-		Map<String, List<CapabilityDefinition>> additionalCap = componentInstance.getCapabilities();
-		Map<String, List<RequirementDefinition>> additionalReq = componentInstance.getRequirements();
-		
-		MapListCapabiltyDataDefinition	allCalculatedCap = calcCap==null ||!calcCap.containsKey(componentInstanceData.getUniqueId())?new MapListCapabiltyDataDefinition() :calcCap.get(componentInstanceData.getUniqueId());
-		/********capability****************************/
-		StorageOperationStatus status = deleteToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, componentInstanceData.getUniqueId());
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty  for instance {} in container {}. error {] ", componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status);
-			return Either.right(status);
-		}
-		
-		if(additionalCap != null && !additionalCap.isEmpty()){
-			
-			Map<String, ListCapabilityDataDefinition> serverCap = additionalCap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, en -> new ListCapabilityDataDefinition(en.getValue().stream().map(iCap -> new CapabilityDataDefinition(iCap)).collect(Collectors.toList()))));
-			
-			serverCap.entrySet().forEach(entryPerType -> {
-					entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
-						cap.addToPath(componentInstance.getUniqueId());							
-						allCalculatedCap.add(entryPerType.getKey(), cap);
-					});
-				});
-			
-			status = addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap,
-					componentInstance.getUniqueId());
-			
-			/********capability property****************************/
-			status = deleteToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, componentInstanceData.getUniqueId());
-			if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty properties for instance {} in container {}. error {] ", componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status);
-				return Either.right(status);
-			}
-			
-			
-			MapCapabiltyProperty	allCalculatedCapProp = calcCapProp==null ||!calcCapProp.containsKey(componentInstanceData.getUniqueId())?new MapCapabiltyProperty() :calcCapProp.get(componentInstanceData.getUniqueId());
-			
+    private Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addServerCapAndReqToProxyServerInstance(TopologyTemplate updatedContainer, ComponentInstance componentInstance,
 
-			additionalCap.forEach(new BiConsumer<String, List<CapabilityDefinition>>() {
-				@Override
-				public void accept(String s, List<CapabilityDefinition> caps) {
+            ComponentInstanceDataDefinition componentInstanceData) {
 
-					if (caps != null && !caps.isEmpty()) {
+        Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result;
 
-						MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
+        Map<String, MapListCapabilityDataDefinition> calcCap = updatedContainer.getCalculatedCapabilities();
+        Map<String, MapListRequirementDataDefinition> calcReg = updatedContainer.getCalculatedRequirements();
+        Map<String, MapCapabilityProperty> calcCapProp = updatedContainer.getCalculatedCapabilitiesProperties();
 
-						for (CapabilityDefinition cap : caps) {
-							List<ComponentInstanceProperty> capPrps = cap.getProperties();
-							if (capPrps != null) {
+        Map<String, List<CapabilityDefinition>> additionalCap = componentInstance.getCapabilities();
+        Map<String, List<RequirementDefinition>> additionalReq = componentInstance.getRequirements();
 
-								for (ComponentInstanceProperty cip : capPrps) {
-									dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
-								}
-							
+        MapListCapabilityDataDefinition allCalculatedCap = calcCap == null || !calcCap.containsKey(componentInstanceData.getUniqueId()) ? new MapListCapabilityDataDefinition() : calcCap.get(componentInstanceData.getUniqueId());
+        /******** capability ****************************/
+        StorageOperationStatus status = deleteToscaDataDeepElementsBlockOfToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, componentInstanceData.getUniqueId());
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty  for instance {} in container {}. error {] ", componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status);
+            return Either.right(status);
+        }
 
-								StringBuffer sb = new StringBuffer(componentInstance.getUniqueId());
-								sb.append(ModelConverter.CAP_PROP_DELIM);
-								
-								sb.append(cap.getOwnerId());
-								
-								sb.append(ModelConverter.CAP_PROP_DELIM).append(s).append(ModelConverter.CAP_PROP_DELIM).append(cap.getName());
-								allCalculatedCapProp.put(sb.toString(), dataToCreate);
-							}
-						}
+        if (additionalCap != null && !additionalCap.isEmpty()) {
 
-					}
+            Map<String, ListCapabilityDataDefinition> serverCap = additionalCap.entrySet().stream()
+                    .collect(Collectors.toMap(Map.Entry::getKey, en -> new ListCapabilityDataDefinition(en.getValue().stream().map(CapabilityDataDefinition::new).collect(Collectors.toList()))));
 
-				}
-			});
-			
-			status = addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, allCalculatedCapProp,
-					componentInstance.getUniqueId());
-		}
-		
-		/********Requirements property****************************/
-		if(additionalReq != null && !additionalReq.isEmpty()){
-		
-			MapListRequirementDataDefinition	allCalculatedReq = calcReg==null ||!calcReg.containsKey(componentInstanceData.getUniqueId())?new MapListRequirementDataDefinition() :calcReg.get(componentInstanceData.getUniqueId());
-			status = deleteToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, componentInstanceData.getUniqueId());
-			if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated Requirements for instance {} in container {}. error {] ", componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status);
-				return Either.right(status);
-			}
-			
-			Map<String, ListRequirementDataDefinition> serverReq = additionalReq.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, en -> new ListRequirementDataDefinition(en.getValue().stream().map(iCap -> new RequirementDataDefinition(iCap)).collect(Collectors.toList()))));
-				
-			serverReq.entrySet().forEach(entryPerType -> {
-					entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
-						cap.addToPath(componentInstance.getUniqueId());							
-						allCalculatedReq.add(entryPerType.getKey(), cap);
-					});
-				});
-			
-			status = addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq,
-					componentInstance.getUniqueId());
-		
-		}
+            serverCap.entrySet().forEach(entryPerType -> {
+                entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
+                    cap.addToPath(componentInstance.getUniqueId());
+                    allCalculatedCap.add(entryPerType.getKey(), cap);
+                });
+            });
 
+            status = addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap, componentInstance.getUniqueId());
 
-		Either<ToscaElement, StorageOperationStatus> updatedComponentInstanceRes = topologyTemplateOperation.getToscaElement(updatedContainer.getUniqueId());
-		if (updatedComponentInstanceRes.isRight()) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with new component instance {}. ", updatedContainer.getName(), componentInstance.getName());
-			result = Either.right(updatedComponentInstanceRes.right().value());
-		}
-		result = Either.left(new ImmutablePair<>((TopologyTemplate)updatedComponentInstanceRes.left().value(), componentInstanceData.getUniqueId()));
-		return result;
-	}
-	
+            /******** capability property ****************************/
+            status = deleteToscaDataDeepElementsBlockOfToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, componentInstanceData.getUniqueId());
+            if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty properties for instance {} in container {}. error {] ", componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status);
+                return Either.right(status);
+            }
 
-	private Either<String, StorageOperationStatus> buildValidateInstanceName(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstance componentInstance, String instanceNumberSuffix) {
+            MapCapabilityProperty allCalculatedCapProp = calcCapProp == null || !calcCapProp.containsKey(componentInstanceData.getUniqueId()) ? new MapCapabilityProperty() : calcCapProp.get(componentInstanceData.getUniqueId());
 
-		Either<String, StorageOperationStatus> result = null;
-		String instanceName = componentInstance.getName();
-		if (StringUtils.isEmpty(instanceName) || instanceName.equalsIgnoreCase(originToscaElement.getName()) || componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
-			instanceName = buildComponentInstanceName(instanceNumberSuffix, instanceName);
-		} else if (!isUniqueInstanceName(container, componentInstance.getName())) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create component instance with name {} on component container {}. The instance with the same name already exists. ", componentInstance.getName(), container.getName());
-			result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
-		}
-		if (result == null) {
-			result = Either.left(instanceName);
-		}
-		return result;
-	}
+            additionalCap.forEach(new BiConsumer<String, List<CapabilityDefinition>>() {
+                @Override
+                public void accept(String s, List<CapabilityDefinition> caps) {
 
-	public Either<TopologyTemplate, StorageOperationStatus> addComponentInstanceToTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstanceDataDefinition componentInstance, GraphVertex metadataVertex,
-			boolean allowDeleted, User user) {
+                    if (caps != null && !caps.isEmpty()) {
 
-		Either<TopologyTemplate, StorageOperationStatus> result = null;
-		Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
-		String containerComponentId = container.getUniqueId();
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to create component instance {} in component {}", componentInstance, containerComponentId);
-		String instOriginComponentId = componentInstance.getComponentUid();
-		Either<GraphVertex, TitanOperationStatus> updateElement = null;
+                        MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
 
-		Boolean isDeleted = (Boolean) originToscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED);
+                        for (CapabilityDefinition cap : caps) {
+                            List<ComponentInstanceProperty> capPrps = cap.getProperties();
+                            if (capPrps != null) {
 
-		if (!allowDeleted && (isDeleted != null) && isDeleted) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance", instOriginComponentId);
-			result = Either.right(StorageOperationStatus.INVALID_ID);
-		}
-		if (result == null) {
-			container.addComponentInstance(componentInstance);
-			metadataVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
-			topologyTemplateOperation.fillToscaElementVertexData(metadataVertex, container, JsonParseFlagEnum.ParseAll);
-			updateElement = titanDao.updateVertex(metadataVertex);
-			if (updateElement.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instance {}. ", container.getName(), componentInstance.getName());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
-			}
-		}
-		if (result == null) {
-			Either<GraphVertex, StorageOperationStatus> addToscaDataRes = addComponentInstanceToscaDataToContainerComponent(originToscaElement, componentInstance, updateElement.left().value(), user);
-			if (addToscaDataRes.isRight()) {
-				result = Either.right(addToscaDataRes.right().value());
-			}
-		}
+                                for (ComponentInstanceProperty cip : capPrps) {
+                                    dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
+                                }
 
-		if (result == null) {
-			updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
-			if (updateContainerComponentRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with new component instance {}. ", container.getName(), componentInstance.getName());
-				result = Either.right(updateContainerComponentRes.right().value());
-			}
-		}
-		if (result == null) {
-			result = Either.left((TopologyTemplate) updateContainerComponentRes.left().value());
-		}
-		return result;
-	}
+                                StringBuffer sb = new StringBuffer(componentInstance.getUniqueId());
+                                sb.append(ModelConverter.CAP_PROP_DELIM);
 
-	public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstance componentInstance) {
+                                sb.append(cap.getOwnerId());
 
-		Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
-		Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
+                                sb.append(ModelConverter.CAP_PROP_DELIM).append(s).append(ModelConverter.CAP_PROP_DELIM).append(cap.getName());
+                                allCalculatedCapProp.put(sb.toString(), dataToCreate);
+                            }
+                        }
 
-		String containerComponentId = container.getUniqueId();
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update component instance metadata {} of container component {}", componentInstance, containerComponentId);
-		ComponentInstanceDataDefinition componentInstanceData = null;
+                    }
 
-		Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
-		if (metadataVertex.isRight()) {
-			TitanOperationStatus status = metadataVertex.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		if (result == null) {
-			componentInstanceData = buildComponentInstanceDataDefinition(componentInstance, container.getUniqueId(), componentInstance.getName(), false, originToscaElement);
-			container.addComponentInstance(componentInstanceData);
-			metadataVertex.left().value().setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
-			topologyTemplateOperation.fillToscaElementVertexData(metadataVertex.left().value(), container, JsonParseFlagEnum.ParseAll);
-			Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(metadataVertex.left().value());
-			if (updateElement.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instance {}. ", container.getName(), componentInstance.getName());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
-			}
-		}
-		if (result == null) {
-			updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
-			if (updateContainerComponentRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with updated component instance {}. ", container.getName(), componentInstance.getName());
-				result = Either.right(updateContainerComponentRes.right().value());
-			}
-		}
-		if (result == null) {
-			result = Either.left(new ImmutablePair<>((TopologyTemplate) updateContainerComponentRes.left().value(), componentInstanceData.getUniqueId()));
-		}
-		return result;
-	}
+                }
+            });
 
-	public Either<TopologyTemplate, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(TopologyTemplate container, ComponentParametersView filter) {
+            status = addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, allCalculatedCapProp, componentInstance.getUniqueId());
+        }
 
-		Either<TopologyTemplate, StorageOperationStatus> result = null;
-		Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
+        /******** Requirements property ****************************/
+        if (additionalReq != null && !additionalReq.isEmpty()) {
 
-		String containerComponentId = container.getUniqueId();
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update component instance metadata  of container component {}", containerComponentId);
+            MapListRequirementDataDefinition allCalculatedReq = calcReg == null || !calcReg.containsKey(componentInstanceData.getUniqueId()) ? new MapListRequirementDataDefinition() : calcReg.get(componentInstanceData.getUniqueId());
+            status = deleteToscaDataDeepElementsBlockOfToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, componentInstanceData.getUniqueId());
+            if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove calculated Requirements for instance {} in container {}. error {] ", componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status);
+                return Either.right(status);
+            }
 
-		Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
-		if (metadataVertex.isRight()) {
-			TitanOperationStatus status = metadataVertex.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		if (result == null) {
-			metadataVertex.left().value().setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
-			topologyTemplateOperation.fillToscaElementVertexData(metadataVertex.left().value(), container, JsonParseFlagEnum.ParseAll);
-			Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(metadataVertex.left().value());
-			if (updateElement.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {}. ", container.getName());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
-			}
-		}
-		if (result == null) {
-			updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId, filter);
-			if (updateContainerComponentRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {}. ", container.getName());
-				result = Either.right(updateContainerComponentRes.right().value());
-			}
-		}
-		if (result == null) {
-			result = Either.left((TopologyTemplate) updateContainerComponentRes.left().value());
-		}
-		return result;
-	}
+            Map<String, ListRequirementDataDefinition> serverReq = additionalReq.entrySet().stream()
+                    .collect(Collectors.toMap(Map.Entry::getKey, en -> new ListRequirementDataDefinition(en.getValue().stream().map(RequirementDataDefinition::new).collect(Collectors.toList()))));
 
-	public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> deleteComponentInstanceFromTopologyTemplate(TopologyTemplate container, String componentInstanceId) {
+            serverReq.entrySet().forEach(entryPerType -> {
+                entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
+                    cap.addToPath(componentInstance.getUniqueId());
+                    allCalculatedReq.add(entryPerType.getKey(), cap);
+                });
+            });
 
-		Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
-		Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
+            status = addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq, componentInstance.getUniqueId());
 
-		String containerComponentId = container.getUniqueId();
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update component instance metadata {} of container component {}", componentInstanceId, containerComponentId);
+        }
 
-		Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
-		if (metadataVertex.isRight()) {
-			TitanOperationStatus status = metadataVertex.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		GraphVertex containerV = null;
-		if (result == null) {
-			container.getComponentInstances().remove(componentInstanceId);
-			containerV = metadataVertex.left().value();
-			StorageOperationStatus status = removeRelationsOfInstance(container, componentInstanceId, containerV);
-			if (status != StorageOperationStatus.OK) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete relation for component instance {} in container. error {}", componentInstanceId, container.getUniqueId(), status);
-				result = Either.right(status);
-			}
+        Either<ToscaElement, StorageOperationStatus> updatedComponentInstanceRes = topologyTemplateOperation.getToscaElement(updatedContainer.getUniqueId());
+        if (updatedComponentInstanceRes.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with new component instance {}. ", updatedContainer.getName(), componentInstance.getName());
+            result = Either.right(updatedComponentInstanceRes.right().value());
+        }
+        result = Either.left(new ImmutablePair<>((TopologyTemplate) updatedComponentInstanceRes.left().value(), componentInstanceData.getUniqueId()));
+        return result;
+    }
 
-			containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
-			topologyTemplateOperation.fillToscaElementVertexData(containerV, container, JsonParseFlagEnum.ParseAll);
-			Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(containerV);
-			if (updateElement.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instance {}. ", container.getName(), componentInstanceId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
-			}
-		}
-		if (result == null) {
-			StorageOperationStatus status = deleteComponentInstanceToscaDataFromContainerComponent(containerV, componentInstanceId);
-			if (status != StorageOperationStatus.OK) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete data  for instance {} in container {}. error {] ", componentInstanceId, container.getUniqueId(), status);
-				return Either.right(status);
-			}
-			updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
-			if (updateContainerComponentRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} after deleting the component instance {}. ", container.getName(), componentInstanceId);
-				result = Either.right(updateContainerComponentRes.right().value());
-			}
-		}
-		if (result == null) {
-			result = Either.left(new ImmutablePair<>((TopologyTemplate) updateContainerComponentRes.left().value(), componentInstanceId));
-		}
-		return result;
-	}
+    private Either<String, StorageOperationStatus> buildValidateInstanceName(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstance componentInstance, String instanceNumberSuffix) {
 
-	private StorageOperationStatus removeRelationsOfInstance(TopologyTemplate container, String ciToRemove, GraphVertex containerV) {
-		CompositionDataDefinition composition = container.getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue());
-		if (composition != null) {
-			Map<String, RelationshipInstDataDefinition> relations = composition.getRelations();
-			if (MapUtils.isNotEmpty(relations)) {
-				Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
-				if (capResult.isRight()) {
-					return capResult.right().value();
+        Either<String, StorageOperationStatus> result = null;
+        String instanceName = componentInstance.getName();
+        if (StringUtils.isEmpty(instanceName) || instanceName.equalsIgnoreCase(originToscaElement.getName()) || componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
+            instanceName = buildComponentInstanceName(instanceNumberSuffix, instanceName);
+        } else if (!isUniqueInstanceName(container, componentInstance.getName())) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create component instance with name {} on component container {}. The instance with the same name already exists. ", componentInstance.getName(), container.getName());
+            result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
+        }
+        if (result == null) {
+            result = Either.left(instanceName);
+        }
+        return result;
+    }
 
-				}
-				Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
+    public Either<TopologyTemplate, StorageOperationStatus> addComponentInstanceToTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstanceDataDefinition componentInstance, GraphVertex metadataVertex,
+            boolean allowDeleted, User user) {
 
-				Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
-				if (capFullResult.isRight()) {
-					return capFullResult.right().value();
+        Either<TopologyTemplate, StorageOperationStatus> result = null;
+        Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
+        String containerComponentId = container.getUniqueId();
+        CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to create component instance {} in component {}", componentInstance, containerComponentId);
+        String instOriginComponentId = componentInstance.getComponentUid();
+        Either<GraphVertex, TitanOperationStatus> updateElement = null;
 
-				}
-				Map<String, MapListCapabiltyDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
+        Boolean isDeleted = (Boolean) originToscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED);
 
-				Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
-				if (reqResult.isRight()) {
-					return reqResult.right().value();
-				}
-				Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
+        if (!allowDeleted && (isDeleted != null) && isDeleted) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance", instOriginComponentId);
+            result = Either.right(StorageOperationStatus.INVALID_ID);
+        }
+        Boolean isArchived = originToscaElement.isArchived();
+        if ( isArchived != null && isArchived ){
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create instance {}. Origin {} component is archived . ", componentInstance.getName(), originToscaElement.getName());
+            result = Either.right(StorageOperationStatus.COMPONENT_IS_ARCHIVED);
+        }
 
-				Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
-				if (reqResult.isRight()) {
-					return reqResult.right().value();
-				}
-				Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
+        if (result == null) {
+            container.addComponentInstance(componentInstance);
+            metadataVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+            topologyTemplateOperation.fillToscaElementVertexData(metadataVertex, container, JsonParseFlagEnum.ParseAll);
+            updateElement = titanDao.updateVertex(metadataVertex);
+            if (updateElement.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_UPDATE_TOPOLOGY_TEMPLATE_WITH_NEW_COMPONENT_INSTANCE, container.getName(), componentInstance.getName());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
+            }
+        }
+        if (result == null) {
+            Either<GraphVertex, StorageOperationStatus> addToscaDataRes = addComponentInstanceToscaDataToContainerComponent(originToscaElement, componentInstance, updateElement.left().value(), user);
+            if (addToscaDataRes.isRight()) {
+                result = Either.right(addToscaDataRes.right().value());
+            }
+        }
+        if (result == null) {
+            StorageOperationStatus createInstanceEdge = createInstanceEdge(metadataVertex, componentInstance);
+            result = createInstanceEdge == StorageOperationStatus.OK ? null : Either.right(createInstanceEdge);
+        }
 
-				Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
-				while (iterator.hasNext()) {
-					Entry<String, RelationshipInstDataDefinition> relation = iterator.next();
-					RelationshipInstDataDefinition relationToDelete = relation.getValue();
-					if (relationToDelete.getFromId().equals(ciToRemove) || relationToDelete.getToId().equals(ciToRemove)) {
-						iterator.remove();
-						if (relationToDelete.getFromId().equals(ciToRemove)) {
-							updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement, ciToRemove, relationToDelete, null);
-							updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, relationToDelete.getToId(), relationToDelete, null);
-						}
-						if (relationToDelete.getToId().equals(ciToRemove)) {
-							updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement, relationToDelete.getFromId(), relationToDelete, null);
-							updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, ciToRemove, relationToDelete, null);
-						}
-					}
-				}
-				return updateAllAndCalculatedCapReqOnGraph(container.getUniqueId(), containerV, capResult, capFullResult, reqResult, reqFullResult);
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+        if (result == null) {
+            updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
+            if (updateContainerComponentRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with new component instance {}. ", container.getName(), componentInstance.getName());
+                result = Either.right(updateContainerComponentRes.right().value());
+            }
+        }
+        if (result == null) {
+            result = Either.left((TopologyTemplate) updateContainerComponentRes.left().value());
+        }
+        return result;
+    }
 
-	private StorageOperationStatus deleteComponentInstanceToscaDataFromContainerComponent(GraphVertex containerV, String componentInstanceId) {
-		StorageOperationStatus status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty properties for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled capabilities  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove attributes for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove properties for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance inputs  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance deployment artifacts  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INSTANCE_ARTIFACTS, VertexTypeEnum.INSTANCE_ARTIFACTS, componentInstanceId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance artifacts  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
-			return status;
-		}
-		return StorageOperationStatus.OK;
-	}
+    public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstance componentInstance) {
 
-	protected Either<GraphVertex, StorageOperationStatus> addComponentInstanceToscaDataToContainerComponent(ToscaElement originToscaElement, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user) {
+        Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
+        Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
 
-		Either<GraphVertex, StorageOperationStatus> result;
-		StorageOperationStatus status;
-		if (originToscaElement.getToscaType() == ToscaElementTypeEnum.NodeType) {
-			status = addComponentInstanceToscaDataToNodeTypeContainer((NodeType) originToscaElement, componentInstance, updatedContainerVertex, user, HEAT_VF_ENV_NAME);
-		} else {
-			status = addComponentInstanceToscaDataToTopologyTemplateContainer((TopologyTemplate) originToscaElement, componentInstance, updatedContainerVertex);
-		}
-		if (status == StorageOperationStatus.OK) {
-			result = Either.left(updatedContainerVertex);
-		} else {
-			result = Either.right(status);
-		}
-		return result;
-	}
+        String containerComponentId = container.getUniqueId();
+        CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update component instance metadata {} of container component {}", componentInstance, containerComponentId);
+        ComponentInstanceDataDefinition componentInstanceData = null;
 
-	private StorageOperationStatus addComponentInstanceToscaDataToTopologyTemplateContainer(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
+        Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
+        if (metadataVertex.isRight()) {
+            TitanOperationStatus status = metadataVertex.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        if (result == null) {
+            componentInstanceData = buildComponentInstanceDataDefinition(componentInstance, container.getUniqueId(), componentInstance.getName(), false, originToscaElement);
+            container.addComponentInstance(componentInstanceData);
+            metadataVertex.left().value().setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+            topologyTemplateOperation.fillToscaElementVertexData(metadataVertex.left().value(), container, JsonParseFlagEnum.ParseAll);
+            Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(metadataVertex.left().value());
+            if (updateElement.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_UPDATE_TOPOLOGY_TEMPLATE_WITH_NEW_COMPONENT_INSTANCE, container.getName(), componentInstance.getName());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
+            }
+        }
+        if (result == null) {
+            updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
+            if (updateContainerComponentRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with updated component instance {}. ", container.getName(), componentInstance.getName());
+                result = Either.right(updateContainerComponentRes.right().value());
+            }
+        }
+        if (result == null) {
+            result = Either.left(new ImmutablePair<>((TopologyTemplate) updateContainerComponentRes.left().value(), componentInstanceData.getUniqueId()));
+        }
+        return result;
+    }
 
-		StorageOperationStatus status;
+    public Either<TopologyTemplate, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(TopologyTemplate container, ComponentParametersView filter) {
 
-		status = addCalculatedCapReqFromTopologyTemplate(originTopologyTemplate, componentInstance, updatedContainerVertex);
+        Either<TopologyTemplate, StorageOperationStatus> result = null;
+        Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
 
-		if (status != StorageOperationStatus.OK) {
+        String containerComponentId = container.getUniqueId();
+        CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update component instance metadata  of container component {}", containerComponentId);
 
-			return status;
-		}
+        Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
+        if (metadataVertex.isRight()) {
+            TitanOperationStatus status = metadataVertex.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        if (result == null) {
+            metadataVertex.left().value().setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+            topologyTemplateOperation.fillToscaElementVertexData(metadataVertex.left().value(), container, JsonParseFlagEnum.ParseAll);
+            Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(metadataVertex.left().value());
+            if (updateElement.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update topology template {}. ", container.getName());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
+            }
+        }
+        if (result == null) {
+            updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId, filter);
+            if (updateContainerComponentRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {}. ", container.getName());
+                result = Either.right(updateContainerComponentRes.right().value());
+            }
+        }
+        if (result == null) {
+            result = Either.left((TopologyTemplate) updateContainerComponentRes.left().value());
+        }
+        return result;
+    }
 
-		MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(originTopologyTemplate.getInputs());
+    public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> deleteComponentInstanceFromTopologyTemplate(TopologyTemplate container, String componentInstanceId) {
 
-		status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, instProperties, componentInstance.getUniqueId());
-		if (status != StorageOperationStatus.OK) {
-			return status;
-		}
+        Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
+        Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
 
-		return status;
-	}
+        String containerComponentId = container.getUniqueId();
+        CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update component instance metadata {} of container component {}", componentInstanceId, containerComponentId);
 
-	private StorageOperationStatus addCalculatedCapReqFromTopologyTemplate(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
-		Map<String, MapListCapabiltyDataDefinition> calculatedCapabilities = originTopologyTemplate.getCalculatedCapabilities();
+        Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
+        if (metadataVertex.isRight()) {
+            TitanOperationStatus status = metadataVertex.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        GraphVertex containerV = null;
+        ComponentInstanceDataDefinition removedComponentInstance = null;
+        if (result == null) {
+            removedComponentInstance = container.getComponentInstances().remove(componentInstanceId);
+            containerV = metadataVertex.left().value();
+            StorageOperationStatus status = removeRelationsOfInstance(container, componentInstanceId, containerV);
+            if (status != StorageOperationStatus.OK) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete relation for component instance {} in container. error {}", componentInstanceId, container.getUniqueId(), status);
+                result = Either.right(status);
+            }
 
-		if (calculatedCapabilities != null) {
-			MapListCapabiltyDataDefinition allCalculatedCap = new MapListCapabiltyDataDefinition();
-			calculatedCapabilities.entrySet().forEach(enntryPerInstance -> {
-				Map<String, ListCapabilityDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
-				mapByType.entrySet().forEach(entryPerType -> {
-					entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
-						cap.addToPath(componentInstance.getUniqueId());
-						allCalculatedCap.add(entryPerType.getKey(), cap);
-					});
-				});
-			});
+            containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+            topologyTemplateOperation.fillToscaElementVertexData(containerV, container, JsonParseFlagEnum.ParseAll);
+            Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(containerV);
+            if (updateElement.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_UPDATE_TOPOLOGY_TEMPLATE_WITH_NEW_COMPONENT_INSTANCE, container.getName(), componentInstanceId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
+            }
+        }
+        if (result == null) {
+            StorageOperationStatus status = deleteComponentInstanceToscaDataFromContainerComponent(containerV, componentInstanceId);
+            if (status != StorageOperationStatus.OK) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete data  for instance {} in container {}. error {] ", componentInstanceId, container.getUniqueId(), status);
+                return Either.right(status);
+            }
+            ComponentInstance componentInstance = new ComponentInstance(removedComponentInstance);
+            StorageOperationStatus createInstanceEdge = removeInstanceEdge(containerV, componentInstance);
+            result = createInstanceEdge == StorageOperationStatus.OK ? null : Either.right(createInstanceEdge);
+        }
+        if (result == null) {
+            updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
+            if (updateContainerComponentRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} after deleting the component instance {}. ", container.getName(), componentInstanceId);
+                result = Either.right(updateContainerComponentRes.right().value());
+            }
+        }
+        if (result == null) {
+            result = Either.left(new ImmutablePair<>((TopologyTemplate) updateContainerComponentRes.left().value(), componentInstanceId));
+        }
+        return result;
+    }
 
-			StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap,
-					componentInstance.getUniqueId());
+    private StorageOperationStatus removeRelationsOfInstance(TopologyTemplate container, String ciToRemove, GraphVertex containerV) {
+        CompositionDataDefinition composition = container.getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue());
+        if (composition != null) {
+            Map<String, RelationshipInstDataDefinition> relations = composition.getRelations();
+            if (MapUtils.isNotEmpty(relations)) {
+                Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
+                if (capResult.isRight()) {
+                    return capResult.right().value();
 
-			if (calculatedResult != StorageOperationStatus.OK) {
-				return calculatedResult;
-			}
-			MapListCapabiltyDataDefinition fullCalculatedCap = new MapListCapabiltyDataDefinition();
-			calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
+                }
+                Map<String, MapListCapabilityDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
 
-			if (calculatedResult != StorageOperationStatus.OK) {
-				return calculatedResult;
-			}
-		}
-		Map<String, MapListRequirementDataDefinition> calculatedRequirements = originTopologyTemplate.getCalculatedRequirements();
-		if (calculatedRequirements != null) {
+                Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
+                if (capFullResult.isRight()) {
+                    return capFullResult.right().value();
 
-			MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
-			calculatedRequirements.entrySet().forEach(enntryPerInstance -> {
-				Map<String, ListRequirementDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
-				mapByType.entrySet().forEach(entryPerType -> {
-					entryPerType.getValue().getListToscaDataDefinition().forEach(req -> {
-						req.addToPath(componentInstance.getUniqueId());
-						allCalculatedReq.add(entryPerType.getKey(), req);
-					});
-				});
-			});
+                }
+                Map<String, MapListCapabilityDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
 
-			StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq,
-					componentInstance.getUniqueId());
-			if (calculatedResult != StorageOperationStatus.OK) {
-				return calculatedResult;
-			}
-			MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
-			calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
-			if (calculatedResult != StorageOperationStatus.OK) {
-				return calculatedResult;
-			}
-		}
+                Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
+                if (reqResult.isRight()) {
+                    return reqResult.right().value();
+                }
+                Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
 
-		Map<String, MapCapabiltyProperty> calculatedCapabilitiesProperties = originTopologyTemplate.getCalculatedCapabilitiesProperties();
-		Map<String, MapPropertiesDataDefinition> updateKeyMap = new HashMap<>();
+                Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
+                if (reqResult.isRight()) {
+                    return reqResult.right().value();
+                }
+                Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
 
-		if (calculatedCapabilitiesProperties != null && !calculatedCapabilitiesProperties.isEmpty()) {
-			for (MapCapabiltyProperty map : calculatedCapabilitiesProperties.values()) {
-				for (Entry<String, MapPropertiesDataDefinition> entry : map.getMapToscaDataDefinition().entrySet()) {
-					String newKey = new String(componentInstance.getUniqueId() + ModelConverter.CAP_PROP_DELIM + entry.getKey());
-					updateKeyMap.put(newKey, entry.getValue());
-				}
-			}
-			MapCapabiltyProperty mapCapabiltyProperty = new MapCapabiltyProperty(updateKeyMap);
-			StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabiltyProperty,
-					componentInstance.getUniqueId());
-			if (calculatedResult != StorageOperationStatus.OK) {
-				return calculatedResult;
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+                Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
+                while (iterator.hasNext()) {
+                    Entry<String, RelationshipInstDataDefinition> relation = iterator.next();
+                    RelationshipInstDataDefinition relationToDelete = relation.getValue();
+                    if (relationToDelete.getFromId().equals(ciToRemove) || relationToDelete.getToId().equals(ciToRemove)) {
+                        iterator.remove();
+                        if (relationToDelete.getFromId().equals(ciToRemove)) {
+                            updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement, ciToRemove, relationToDelete, null);
+                            updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, relationToDelete.getToId(), relationToDelete, null);
+                        }
+                        if (relationToDelete.getToId().equals(ciToRemove)) {
+                            updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement, relationToDelete.getFromId(), relationToDelete, null);
+                            updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, ciToRemove, relationToDelete, null);
+                        }
+                    }
+                }
+                return updateAllAndCalculatedCapReqOnGraph(container.getUniqueId(), containerV, capResult, capFullResult, reqResult, reqFullResult);
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private StorageOperationStatus addComponentInstanceToscaDataToNodeTypeContainer(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user, String envType) {
+    private StorageOperationStatus deleteComponentInstanceToscaDataFromContainerComponent(GraphVertex containerV, String componentInstanceId) {
+        StorageOperationStatus status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty properties for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove calculated requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove fullfilled capabilities  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove attributes for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove properties for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove instance inputs  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove instance deployment artifacts  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INSTANCE_ARTIFACTS, VertexTypeEnum.INSTANCE_ARTIFACTS, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove instance artifacts  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.EXTERNAL_REFS, VertexTypeEnum.EXTERNAL_REF, componentInstanceId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove instance external refs  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
+            return status;
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(originNodeType.getProperties());
+    protected Either<GraphVertex, StorageOperationStatus> addComponentInstanceToscaDataToContainerComponent(ToscaElement originToscaElement, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user) {
 
-		StorageOperationStatus status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, instProperties, componentInstance.getUniqueId());
-		if (status != StorageOperationStatus.OK) {
-			return status;
-		}
+        Either<GraphVertex, StorageOperationStatus> result;
+        StorageOperationStatus status;
+        if (originToscaElement.getToscaType() == ToscaElementTypeEnum.NODE_TYPE) {
+            status = addComponentInstanceToscaDataToNodeTypeContainer((NodeType) originToscaElement, componentInstance, updatedContainerVertex, user, HEAT_VF_ENV_NAME);
+        } else {
+            status = addComponentInstanceToscaDataToTopologyTemplateContainer((TopologyTemplate) originToscaElement, componentInstance, updatedContainerVertex);
+        }
+        if (status == StorageOperationStatus.OK) {
+            result = Either.left(updatedContainerVertex);
+        } else {
+            result = Either.right(status);
+        }
+        return result;
+    }
 
-		MapPropertiesDataDefinition instAttributes = new MapPropertiesDataDefinition(originNodeType.getAttributes());
+    private StorageOperationStatus addComponentInstanceToscaDataToTopologyTemplateContainer(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
 
-		status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, instAttributes, componentInstance.getUniqueId());
+        StorageOperationStatus status;
 
-		if (status != StorageOperationStatus.OK) {
-			return status;
-		}
+        status = addCalculatedCapReqFromTopologyTemplate(originTopologyTemplate, componentInstance, updatedContainerVertex);
 
-		return addCalculatedCapReqFromNodeType(originNodeType, componentInstance, updatedContainerVertex);
-	}
+        if (status != StorageOperationStatus.OK) {
 
-	public MapArtifactDataDefinition prepareInstDeploymentArtifactPerInstance(Map<String, ArtifactDataDefinition> deploymentArtifacts, String componentInstanceId, User user, String envType) {
-		if (deploymentArtifacts != null && envType.equals(HEAT_VF_ENV_NAME)) {
-			Map<String, ArtifactDataDefinition> instDeploymentArtifacts = new HashMap<>();
+            return status;
+        }
 
-			deploymentArtifacts.entrySet().forEach(e -> {
-				ArtifactDataDefinition artifact = e.getValue();
-				String type = artifact.getArtifactType();
-				if (type.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) {
-					ArtifactDataDefinition artifactEnv = createArtifactPlaceHolderInfo(artifact, componentInstanceId, user, envType);
-					instDeploymentArtifacts.put(artifactEnv.getArtifactLabel(), artifactEnv);
-				}
-			});
+        MapPropertiesDataDefinition instInputs = new MapPropertiesDataDefinition(originTopologyTemplate.getInputs());
+        MapPropertiesDataDefinition instInputsAsProperties = turnInputsIntoProperties(instInputs);
 
-			deploymentArtifacts.putAll(instDeploymentArtifacts);
-			MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(deploymentArtifacts);
+        status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, instInputsAsProperties, componentInstance.getUniqueId());
+        if (status != StorageOperationStatus.OK) {
+            return status;
+        }
 
-			return instArtifacts;
-		}
-		return null;
-	}
+        return status;
+    }
+    
+    private MapPropertiesDataDefinition turnInputsIntoProperties(MapPropertiesDataDefinition instInput){
+        if (instInput.getMapToscaDataDefinition() != null) {
+            for (PropertyDataDefinition currProp : instInput.getMapToscaDataDefinition().values()){
+                String temp = currProp.getValue();
+                currProp.setValue(currProp.getDefaultValue());
+                currProp.setDefaultValue(temp);
+            }
+        }
+        return instInput;
+    }
 
-	@SuppressWarnings({ "unchecked" })
-	private ArtifactDataDefinition createArtifactPlaceHolderInfo(ArtifactDataDefinition artifactHeat, String componentId, User user, String heatEnvType) {
-		Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getDeploymentResourceInstanceArtifacts();
-		if (deploymentResourceArtifacts == null) {
-			logger.debug("no deployment artifacts are configured for generated artifacts");
-			return null;
-		}
-		Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(heatEnvType);
-		if (placeHolderData == null) {
-			logger.debug("no env type {} are configured for generated artifacts", heatEnvType);
-			return null;
-		}
+    private StorageOperationStatus addCalculatedCapReqFromTopologyTemplate(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
+        Map<String, MapListCapabilityDataDefinition> calculatedCapabilities = originTopologyTemplate.getCalculatedCapabilities();
 
-		String envLabel = (artifactHeat.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
+        if (calculatedCapabilities != null) {
+            MapListCapabilityDataDefinition allCalculatedCap = new MapListCapabilityDataDefinition();
+            calculatedCapabilities.entrySet().forEach(enntryPerInstance -> {
+                Map<String, ListCapabilityDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
+                mapByType.entrySet().forEach(entryPerType -> {
+                    entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
+                        cap.addToPath(componentInstance.getUniqueId());
+                        allCalculatedCap.add(entryPerType.getKey(), cap);
+                    });
+                });
+            });
 
-		ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition();
+            StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap,
+                    componentInstance.getUniqueId());
 
-		String artifactName = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
-		String artifactType = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_TYPE);
-		String artifactDescription = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
+            if (calculatedResult != StorageOperationStatus.OK) {
+                return calculatedResult;
+            }
+            MapListCapabilityDataDefinition fullCalculatedCap = new MapListCapabilityDataDefinition();
+            calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
 
-		artifactInfo.setArtifactDisplayName(artifactName);
-		artifactInfo.setArtifactLabel(envLabel);
-		artifactInfo.setArtifactType(artifactType);
-		artifactInfo.setDescription(artifactDescription);
-		artifactInfo.setArtifactGroupType(artifactHeat.getArtifactGroupType());
-		setDefaultArtifactTimeout(artifactHeat.getArtifactGroupType(), artifactInfo);
-		artifactInfo.setGeneratedFromId(artifactHeat.getUniqueId());
-		// clone heat parameters in case of heat env only not VF heat env
-		if (heatEnvType.equals(HEAT_ENV_NAME)) {
-			artifactInfo.setHeatParameters(artifactHeat.getHeatParameters());
-		}
-		setArtifactPlaceholderCommonFields(componentId, user, artifactInfo);
+            if (calculatedResult != StorageOperationStatus.OK) {
+                return calculatedResult;
+            }
+        }
+        Map<String, MapListRequirementDataDefinition> calculatedRequirements = originTopologyTemplate.getCalculatedRequirements();
+        if (calculatedRequirements != null) {
 
-		return artifactInfo;
-	}
+            MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
+            calculatedRequirements.entrySet().forEach(enntryPerInstance -> {
+                Map<String, ListRequirementDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
+                mapByType.entrySet().forEach(entryPerType -> {
+                    entryPerType.getValue().getListToscaDataDefinition().forEach(req -> {
+                        req.addToPath(componentInstance.getUniqueId());
+                        allCalculatedReq.add(entryPerType.getKey(), req);
+                    });
+                });
+            });
 
-	public void setDefaultArtifactTimeout(ArtifactGroupTypeEnum groupType, ArtifactDataDefinition artifactInfo) {
-		if (groupType.equals(ArtifactGroupTypeEnum.DEPLOYMENT)) {
-			artifactInfo.setTimeout(defaultHeatTimeout);
-		} else {
-			artifactInfo.setTimeout(NON_HEAT_TIMEOUT);
-		}
-	}
+            StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq,
+                    componentInstance.getUniqueId());
+            if (calculatedResult != StorageOperationStatus.OK) {
+                return calculatedResult;
+            }
+            MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
+            calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
+            if (calculatedResult != StorageOperationStatus.OK) {
+                return calculatedResult;
+            }
+        }
 
-	private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDataDefinition artifactInfo) {
-		String uniqueId = null;
+        Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties = originTopologyTemplate.getCalculatedCapabilitiesProperties();
+        Map<String, MapPropertiesDataDefinition> updateKeyMap = new HashMap<>();
 
-		if (resourceId != null) {
-			uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
-			artifactInfo.setUniqueId(uniqueId);
-		}
-		artifactInfo.setUserIdCreator(user.getUserId());
-		String fullName = user.getFullName();
-		artifactInfo.setUpdaterFullName(fullName);
+        if (calculatedCapabilitiesProperties != null && !calculatedCapabilitiesProperties.isEmpty()) {
+            for (MapCapabilityProperty map : calculatedCapabilitiesProperties.values()) {
+                for (Entry<String, MapPropertiesDataDefinition> entry : map.getMapToscaDataDefinition().entrySet()) {
+                    String newKey = (componentInstance.getUniqueId() + ModelConverter.CAP_PROP_DELIM + entry.getKey());
+                    updateKeyMap.put(newKey, entry.getValue());
+                }
+            }
+            MapCapabilityProperty MapCapabilityProperty = new MapCapabilityProperty(updateKeyMap);
+            StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, MapCapabilityProperty,
+                    componentInstance.getUniqueId());
+            if (calculatedResult != StorageOperationStatus.OK) {
+                return calculatedResult;
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		long time = System.currentTimeMillis();
+    private StorageOperationStatus addComponentInstanceToscaDataToNodeTypeContainer(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user, String envType) {
 
-		artifactInfo.setCreatorFullName(fullName);
-		artifactInfo.setCreationDate(time);
+        MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(originNodeType.getProperties());
 
-		artifactInfo.setLastUpdateDate(time);
-		artifactInfo.setUserIdLastUpdater(user.getUserId());
+        StorageOperationStatus status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, instProperties, componentInstance.getUniqueId());
+        if (status != StorageOperationStatus.OK) {
+            return status;
+        }
 
-		artifactInfo.setMandatory(true);
-	}
+        MapPropertiesDataDefinition instAttributes = new MapPropertiesDataDefinition(originNodeType.getAttributes());
 
-	/**
-	 * 
-	 * @param originNodeType
-	 * @param componentInstance
-	 * @param updatedContainerVertex
-	 * @return
-	 */
-	private StorageOperationStatus addCalculatedCapReqFromNodeType(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
+        status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, instAttributes, componentInstance.getUniqueId());
 
-		Map<String, ListCapabilityDataDefinition> capabilities = originNodeType.getCapabilties();
-		MapListCapabiltyDataDefinition allCalculatedCap = prepareCalculatedCapabiltyForNodeType(capabilities, componentInstance);
-		StorageOperationStatus calculatedResult;
-		if (allCalculatedCap != null) {
-			calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap, componentInstance.getUniqueId());
+        if (status != StorageOperationStatus.OK) {
+            return status;
+        }
 
-			if (calculatedResult != StorageOperationStatus.OK) {
-				return calculatedResult;
-			}
-		}
-		Map<String, MapPropertiesDataDefinition> capabiltiesProperties = originNodeType.getCapabiltiesProperties();
-		if (capabiltiesProperties != null) {
-			Map<String, MapPropertiesDataDefinition> updateKeyMap = capabiltiesProperties.entrySet().stream().collect(Collectors.toMap(e -> createCapPropertyKey(e.getKey(), componentInstance.getUniqueId()), e -> e.getValue()));
-			MapCapabiltyProperty mapCapabiltyProperty = new MapCapabiltyProperty(updateKeyMap);
-			calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabiltyProperty, componentInstance.getUniqueId());
-			if (calculatedResult != StorageOperationStatus.OK) {
-				return calculatedResult;
-			}
-		}
+        return addCalculatedCapReqFromNodeType(originNodeType, componentInstance, updatedContainerVertex);
+    }
 
-		MapListCapabiltyDataDefinition fullCalculatedCap = new MapListCapabiltyDataDefinition();
-		calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
+    public MapArtifactDataDefinition prepareInstDeploymentArtifactPerInstance(Map<String, ArtifactDataDefinition> deploymentArtifacts, String componentInstanceId, User user, String envType) {
+        if (deploymentArtifacts != null && envType.equals(HEAT_VF_ENV_NAME)) {
+            Map<String, ArtifactDataDefinition> instDeploymentArtifacts = new HashMap<>();
 
-		if (calculatedResult != StorageOperationStatus.OK) {
-			return calculatedResult;
-		}
+            deploymentArtifacts.entrySet().forEach(e -> {
+                ArtifactDataDefinition artifact = e.getValue();
+                String type = artifact.getArtifactType();
+                if (type.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) {
+                    ArtifactDataDefinition artifactEnv = createArtifactPlaceHolderInfo(artifact, componentInstanceId, user, envType);
+                    instDeploymentArtifacts.put(artifactEnv.getArtifactLabel(), artifactEnv);
+                }
+            });
 
-		Map<String, ListRequirementDataDefinition> requirements = originNodeType.getRequirements();
+            deploymentArtifacts.putAll(instDeploymentArtifacts);
 
-		MapListRequirementDataDefinition allCalculatedReq = prepareCalculatedRequirementForNodeType(requirements, componentInstance);
+            return new MapArtifactDataDefinition(deploymentArtifacts);
 
-		StorageOperationStatus status;
-		if (allCalculatedReq != null) {
-			status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq, componentInstance.getUniqueId());
-			if (status != StorageOperationStatus.OK) {
-				return status;
-			}
-		}
-		MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
-		status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
-		return StorageOperationStatus.OK;
+        }
+        return null;
+    }
 
-	}
+    @SuppressWarnings({ "unchecked" })
+    private ArtifactDataDefinition createArtifactPlaceHolderInfo(ArtifactDataDefinition artifactHeat, String componentId, User user, String heatEnvType) {
+        Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getDeploymentResourceInstanceArtifacts();
+        if (deploymentResourceArtifacts == null) {
+            log.debug("no deployment artifacts are configured for generated artifacts");
+            return null;
+        }
+        Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(heatEnvType);
+        if (placeHolderData == null) {
+            log.debug("no env type {} are configured for generated artifacts", heatEnvType);
+            return null;
+        }
 
-	public static String createCapPropertyKey(String key, String instanceId) {
-		StringBuffer sb = new StringBuffer(instanceId);
-		sb.append(ModelConverter.CAP_PROP_DELIM).append(instanceId).append(ModelConverter.CAP_PROP_DELIM).append(key);
-		return sb.toString();
-	}
-	
-	/**
-	 * Prepares a map of capabilities lists
-	 * Produces a deep copy of the received map of capabilities
-	 * Sets values to the specific fields according to received component instance 
-	 * @param capabilities
-	 * @param componentInstance
-	 * @return
-	 */
-	public MapListCapabiltyDataDefinition prepareCalculatedCapabiltyForNodeType(Map<String, ListCapabilityDataDefinition> capabilities, ComponentInstanceDataDefinition componentInstance) {
-		if (capabilities != null) {
-			MapListCapabiltyDataDefinition allCalculatedCap = new MapListCapabiltyDataDefinition();
+        String envLabel = (artifactHeat.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
 
-			capabilities.entrySet().forEach(e -> {
-				List<CapabilityDataDefinition> listCapabilities = e.getValue().getListToscaDataDefinition().stream().map(c -> new CapabilityDataDefinition(c)).collect(Collectors.toList());
-				listCapabilities.forEach(cap -> {
-					cap.setSource(componentInstance.getComponentUid());
-					cap.addToPath(componentInstance.getUniqueId());
-					cap.setOwnerId(componentInstance.getUniqueId());
-					cap.setOwnerName(componentInstance.getName());
-					cap.setLeftOccurrences(cap.getMaxOccurrences());
-					allCalculatedCap.add(e.getKey(), cap);
-				});
-			});
-			return allCalculatedCap;
-		}
-		return null;
-	}
+        ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition();
 
-	/**
-	 * Prepares a map of requirements lists
-	 * Produces a deep copy of the received map of requirements
-	 * Sets values to the specific fields according to received component instance 
-	 * @param requirements
-	 * @param componentInstance
-	 * @return
-	 */
-	public MapListRequirementDataDefinition prepareCalculatedRequirementForNodeType(Map<String, ListRequirementDataDefinition> requirements, ComponentInstanceDataDefinition componentInstance) {
-		if (requirements != null) {
-			MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
+        String artifactName = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
+        String artifactType = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_TYPE);
+        String artifactDescription = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
 
-			requirements.entrySet().forEach(e -> {
-				List<RequirementDataDefinition> listRequirements = e.getValue().getListToscaDataDefinition().stream().map(r -> new RequirementDataDefinition(r)).collect(Collectors.toList());
-				listRequirements.forEach(req -> {
-					req.setSource(componentInstance.getComponentUid());
-					req.addToPath(componentInstance.getUniqueId());
-					req.setOwnerId(componentInstance.getUniqueId());
-					req.setOwnerName(componentInstance.getName());
-					req.setLeftOccurrences(req.getMaxOccurrences());
-					allCalculatedReq.add(e.getKey(), req);
-				});
-			});
-			return allCalculatedReq;
-		}
-		return null;
-	}
+        artifactInfo.setArtifactDisplayName(artifactName);
+        artifactInfo.setArtifactLabel(envLabel);
+        artifactInfo.setArtifactType(artifactType);
+        artifactInfo.setDescription(artifactDescription);
+        artifactInfo.setArtifactGroupType(artifactHeat.getArtifactGroupType());
+        setDefaultArtifactTimeout(artifactHeat.getArtifactGroupType(), artifactInfo);
+        artifactInfo.setGeneratedFromId(artifactHeat.getUniqueId());
+        // clone heat parameters in case of heat env only not VF heat env
+        if (heatEnvType.equals(HEAT_ENV_NAME)) {
+            artifactInfo.setHeatParameters(artifactHeat.getHeatParameters());
+        }
+        setArtifactPlaceholderCommonFields(componentId, user, artifactInfo);
 
-	public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstanceDataDefinition componentInstance, List<GroupDefinition> groups, Map<String, List<ArtifactDefinition>> groupInstancesArtifacts) {
+        return artifactInfo;
+    }
 
-		StorageOperationStatus result = null;
-		Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
-		if (groupInstancesArtifacts != null && CollectionUtils.isNotEmpty(groups)) {
-			for (Map.Entry<String, List<ArtifactDefinition>> groupArtifacts : groupInstancesArtifacts.entrySet()) {
-				Optional<GroupDefinition> groupOptional = groups.stream().filter(g -> g.getUniqueId().equals(groupArtifacts.getKey())).findFirst();
-				if (groupOptional.isPresent()) {
-					GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition((GroupDataDefinition) groupOptional.get(), (ComponentInstanceDataDefinition) componentInstance, null);
-					groupInstance.setGroupInstanceArtifacts(groupArtifacts.getValue().stream().map(a -> a.getUniqueId()).collect(Collectors.toList()));
-					groupInstance.setGroupInstanceArtifactsUuid(groupArtifacts.getValue().stream().map(a -> a.getArtifactUUID()).collect(Collectors.toList()));
-					groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
-				}
-			}
-		}
-		if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
-			result = addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, new MapDataDefinition<>(groupInstanceToCreate), componentInstance.getUniqueId());
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+    public void setDefaultArtifactTimeout(ArtifactGroupTypeEnum groupType, ArtifactDataDefinition artifactInfo) {
+        if (groupType.equals(ArtifactGroupTypeEnum.DEPLOYMENT)) {
+            artifactInfo.setTimeout(defaultHeatTimeout);
+        } else {
+            artifactInfo.setTimeout(NON_HEAT_TIMEOUT);
+        }
+    }
 
-	private ComponentInstanceDataDefinition buildComponentInstanceDataDefinition(ComponentInstance resourceInstance, String containerComponentId, String instanceNewName, boolean generateUid, ToscaElement originToscaElement) {
-		String ciOriginComponentUid = resourceInstance.getComponentUid();
+    private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDataDefinition artifactInfo) {
+        String uniqueId = null;
 
-		if (!ValidationUtils.validateStringNotEmpty(resourceInstance.getCustomizationUUID())) {
-			resourceInstance.setCustomizationUUID(generateCustomizationUUID());
-		}
-		ComponentInstanceDataDefinition dataDefinition = new ComponentInstanceDataDefinition(resourceInstance);
+        if (resourceId != null) {
+            uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
+            artifactInfo.setUniqueId(uniqueId);
+        }
+        artifactInfo.setUserIdCreator(user.getUserId());
+        String fullName = user.getFullName();
+        artifactInfo.setUpdaterFullName(fullName);
 
-		Long creationDate = resourceInstance.getCreationTime();
-		Long modificationTime;
-		if (creationDate == null) {
-			creationDate = System.currentTimeMillis();
-			modificationTime = creationDate;
-		} else {
-			modificationTime = System.currentTimeMillis();
-		}
-		dataDefinition.setComponentUid(ciOriginComponentUid);
-		dataDefinition.setCreationTime(creationDate);
-		dataDefinition.setModificationTime(modificationTime);
-		if (StringUtils.isNotEmpty(instanceNewName)) {
-			dataDefinition.setName(instanceNewName);
-			resourceInstance.setName(instanceNewName);
-		}
-		if (StringUtils.isNotEmpty(dataDefinition.getName()))
-			dataDefinition.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(dataDefinition.getName()));
-		dataDefinition.setIcon(resourceInstance.getIcon());
-		if (generateUid) {
-			dataDefinition.setUniqueId(UniqueIdBuilder.buildResourceInstanceUniuqeId(containerComponentId, ciOriginComponentUid, dataDefinition.getNormalizedName()));
-			resourceInstance.setUniqueId(dataDefinition.getUniqueId());
-		}
-		if (StringUtils.isEmpty(dataDefinition.getComponentVersion()) && originToscaElement != null)
-			dataDefinition.setComponentVersion((String) originToscaElement.getMetadataValue(JsonPresentationFields.VERSION));
-		if (StringUtils.isEmpty(dataDefinition.getComponentName()) && originToscaElement != null)
-			dataDefinition.setComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.NAME));
-		if (originToscaElement != null && dataDefinition.getToscaComponentName() == null)
-			dataDefinition.setToscaComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
-		if (dataDefinition.getOriginType() == null && originToscaElement != null) {
-			ResourceTypeEnum resourceType = originToscaElement.getResourceType();
-			OriginTypeEnum originType = OriginTypeEnum.findByValue(resourceType.name());
-			dataDefinition.setOriginType(originType);
-		}
-		if(dataDefinition.getOriginType()  == OriginTypeEnum.ServiceProxy)
-			dataDefinition.setIsProxy(true);
-	
-		return dataDefinition;
-	}
+        long time = System.currentTimeMillis();
 
-	private Boolean isUniqueInstanceName(TopologyTemplate container, String instanceName) {
-		Boolean isUniqueName = true;
-		try {
-			isUniqueName = !container.getComponentInstances().values().stream().filter(ci -> ci.getName() != null && ci.getName().equals(instanceName)).findAny().isPresent();
+        artifactInfo.setCreatorFullName(fullName);
+        artifactInfo.setCreationDate(time);
 
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during fetching component instance with name {} from component container {}. {} ", instanceName, container.getName(), e.getMessage());
-		}
-		return isUniqueName;
-	}
+        artifactInfo.setLastUpdateDate(time);
+        artifactInfo.setUserIdLastUpdater(user.getUserId());
+
+        artifactInfo.setMandatory(true);
+    }
+
+    /**
+     *
+     * @param originNodeType
+     * @param componentInstance
+     * @param updatedContainerVertex
+     * @return
+     */
+    private StorageOperationStatus addCalculatedCapReqFromNodeType(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
+
+        Map<String, ListCapabilityDataDefinition> capabilities = originNodeType.getCapabilties();
+        MapListCapabilityDataDefinition allCalculatedCap = prepareCalculatedCapabiltyForNodeType(capabilities, componentInstance);
+        StorageOperationStatus calculatedResult;
+        if (allCalculatedCap != null) {
+            calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap, componentInstance.getUniqueId());
+
+            if (calculatedResult != StorageOperationStatus.OK) {
+                return calculatedResult;
+            }
+        }
+        Map<String, MapPropertiesDataDefinition> capabiltiesProperties = originNodeType.getCapabiltiesProperties();
+        if (capabiltiesProperties != null) {
+            Map<String, MapPropertiesDataDefinition> updateKeyMap = capabiltiesProperties.entrySet().stream().collect(Collectors.toMap(e -> createCapPropertyKey(e.getKey(), componentInstance.getUniqueId()), Entry::getValue));
+            MapCapabilityProperty MapCapabilityProperty = new MapCapabilityProperty(updateKeyMap);
+            calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, MapCapabilityProperty, componentInstance.getUniqueId());
+            if (calculatedResult != StorageOperationStatus.OK) {
+                return calculatedResult;
+            }
+        }
+
+        MapListCapabilityDataDefinition fullCalculatedCap = new MapListCapabilityDataDefinition();
+        calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
+
+        if (calculatedResult != StorageOperationStatus.OK) {
+            return calculatedResult;
+        }
+
+        Map<String, ListRequirementDataDefinition> requirements = originNodeType.getRequirements();
+
+        MapListRequirementDataDefinition allCalculatedReq = prepareCalculatedRequirementForNodeType(requirements, componentInstance);
+
+        StorageOperationStatus status;
+        if (allCalculatedReq != null) {
+            status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq, componentInstance.getUniqueId());
+            if (status != StorageOperationStatus.OK) {
+                return status;
+            }
+        }
+        MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
+        status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
+        return StorageOperationStatus.OK;
+
+    }
+
+    public static String createCapPropertyKey(String key, String instanceId) {
+        StringBuffer sb = new StringBuffer(instanceId);
+        sb.append(ModelConverter.CAP_PROP_DELIM).append(instanceId).append(ModelConverter.CAP_PROP_DELIM).append(key);
+        return sb.toString();
+    }
+
+    /**
+     * Prepares a map of capabilities lists Produces a deep copy of the received map of capabilities Sets values to the specific fields according to received component instance
+     * 
+     * @param capabilities
+     * @param componentInstance
+     * @return
+     */
+    public MapListCapabilityDataDefinition prepareCalculatedCapabiltyForNodeType(Map<String, ListCapabilityDataDefinition> capabilities, ComponentInstanceDataDefinition componentInstance) {
+        if (capabilities != null) {
+            MapListCapabilityDataDefinition allCalculatedCap = new MapListCapabilityDataDefinition();
+
+            capabilities.entrySet().forEach(e -> {
+                List<CapabilityDataDefinition> listCapabilities = e.getValue().getListToscaDataDefinition().stream().map(CapabilityDataDefinition::new).collect(Collectors.toList());
+                listCapabilities.forEach(cap -> {
+                    cap.setSource(componentInstance.getComponentUid());
+                    cap.addToPath(componentInstance.getUniqueId());
+                    cap.setOwnerId(componentInstance.getUniqueId());
+                    cap.setOwnerName(componentInstance.getName());
+                    cap.setLeftOccurrences(cap.getMaxOccurrences());
+                    allCalculatedCap.add(e.getKey(), cap);
+                });
+            });
+            return allCalculatedCap;
+        }
+        return null;
+    }
+
+    /**
+     * Prepares a map of requirements lists Produces a deep copy of the received map of requirements Sets values to the specific fields according to received component instance
+     * 
+     * @param requirements
+     * @param componentInstance
+     * @return
+     */
+    public MapListRequirementDataDefinition prepareCalculatedRequirementForNodeType(Map<String, ListRequirementDataDefinition> requirements, ComponentInstanceDataDefinition componentInstance) {
+        if (requirements != null) {
+            MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
+
+            requirements.entrySet().forEach(e -> {
+                List<RequirementDataDefinition> listRequirements = e.getValue().getListToscaDataDefinition().stream().map(RequirementDataDefinition::new).collect(Collectors.toList());
+                listRequirements.forEach(req -> {
+                    req.setSource(componentInstance.getComponentUid());
+                    req.addToPath(componentInstance.getUniqueId());
+                    req.setOwnerId(componentInstance.getUniqueId());
+                    req.setOwnerName(componentInstance.getName());
+                    req.setLeftOccurrences(req.getMaxOccurrences());
+                    allCalculatedReq.add(e.getKey(), req);
+                });
+            });
+            return allCalculatedReq;
+        }
+        return null;
+    }
+
+    public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstanceDataDefinition componentInstance, List<GroupDefinition> groups, Map<String, List<ArtifactDefinition>> groupInstancesArtifacts) {
+
+        StorageOperationStatus result = null;
+        Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
+        if (groupInstancesArtifacts != null && CollectionUtils.isNotEmpty(groups)) {
+            for (Map.Entry<String, List<ArtifactDefinition>> groupArtifacts : groupInstancesArtifacts.entrySet()) {
+                Optional<GroupDefinition> groupOptional = groups.stream().filter(g -> g.getUniqueId().equals(groupArtifacts.getKey())).findFirst();
+                if (groupOptional.isPresent()) {
+                    GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition((GroupDataDefinition) groupOptional.get(), (ComponentInstanceDataDefinition) componentInstance, null);
+                    groupInstance.setGroupInstanceArtifacts(groupArtifacts.getValue().stream().map(ArtifactDataDefinition::getUniqueId).collect(Collectors.toList()));
+                    groupInstance.setGroupInstanceArtifactsUuid(groupArtifacts.getValue().stream().map(ArtifactDataDefinition::getArtifactUUID).collect(Collectors.toList()));
+                    groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
+                }
+            }
+        }
+        if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
+            result = addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, new MapDataDefinition<>(groupInstanceToCreate), componentInstance.getUniqueId());
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
+
+    private ComponentInstanceDataDefinition buildComponentInstanceDataDefinition(ComponentInstance resourceInstance, String containerComponentId, String instanceNewName, boolean generateUid, ToscaElement originToscaElement) {
+        String ciOriginComponentUid = resourceInstance.getComponentUid();
+
+        if (!ValidationUtils.validateStringNotEmpty(resourceInstance.getCustomizationUUID())) {
+            resourceInstance.setCustomizationUUID(generateCustomizationUUID());
+        }
+        ComponentInstanceDataDefinition dataDefinition = new ComponentInstanceDataDefinition(resourceInstance);
+
+        Long creationDate = resourceInstance.getCreationTime();
+        Long modificationTime;
+        if (creationDate == null) {
+            creationDate = System.currentTimeMillis();
+            modificationTime = creationDate;
+        } else {
+            modificationTime = System.currentTimeMillis();
+        }
+        dataDefinition.setComponentUid(ciOriginComponentUid);
+        dataDefinition.setCreationTime(creationDate);
+        dataDefinition.setModificationTime(modificationTime);
+        if (StringUtils.isNotEmpty(instanceNewName)) {
+            dataDefinition.setName(instanceNewName);
+            resourceInstance.setName(instanceNewName);
+        }
+        if (StringUtils.isNotEmpty(dataDefinition.getName()))
+            dataDefinition.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(dataDefinition.getName()));
+        dataDefinition.setIcon(resourceInstance.getIcon());
+        if (generateUid) {
+            dataDefinition.setUniqueId(UniqueIdBuilder.buildResourceInstanceUniuqeId(containerComponentId, ciOriginComponentUid, dataDefinition.getNormalizedName()));
+            resourceInstance.setUniqueId(dataDefinition.getUniqueId());
+        }
+        if (StringUtils.isEmpty(dataDefinition.getComponentVersion()) && originToscaElement != null)
+            dataDefinition.setComponentVersion((String) originToscaElement.getMetadataValue(JsonPresentationFields.VERSION));
+        if (StringUtils.isEmpty(dataDefinition.getComponentName()) && originToscaElement != null)
+            dataDefinition.setComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.NAME));
+        if (originToscaElement != null && dataDefinition.getToscaComponentName() == null)
+            dataDefinition.setToscaComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
+        if (dataDefinition.getOriginType() == null && originToscaElement != null) {
+            ResourceTypeEnum resourceType = originToscaElement.getResourceType();
+            OriginTypeEnum originType = OriginTypeEnum.findByValue(resourceType.name());
+            dataDefinition.setOriginType(originType);
+        }
+        if (dataDefinition.getOriginType() == OriginTypeEnum.ServiceProxy)
+            dataDefinition.setIsProxy(true);
+
+        return dataDefinition;
+    }
+
+    private Boolean isUniqueInstanceName(TopologyTemplate container, String instanceName) {
+        Boolean isUniqueName = true;
+        try {
+            isUniqueName = !container.getComponentInstances().values().stream().filter(ci -> ci.getName() != null && ci.getName().equals(instanceName)).findAny().isPresent();
+
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during fetching component instance with name {} from component container {}. {} ", instanceName, container.getName(), e.getMessage());
+        }
+        return isUniqueName;
+    }
+
+    private String buildComponentInstanceName(String instanceSuffixNumber, String instanceName) {
+        return instanceName + " " + (instanceSuffixNumber == null ? 0 : instanceSuffixNumber);
+    }
+
+    public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String componentId, RequirementCapabilityRelDef relation) {
+        List<RequirementCapabilityRelDef> relations = new ArrayList<>();
+        relations.add(relation);
+        Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances = associateResourceInstances(componentId, relations);
+        if (associateResourceInstances.isRight()) {
+            return Either.right(associateResourceInstances.right().value());
+        }
+        return Either.left(associateResourceInstances.left().value().get(0));
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    public <T extends ToscaDataDefinition> Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances(String componentId, List<RequirementCapabilityRelDef> relations) {
+
+        Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
+        if (containerVEither.isRight()) {
+            TitanOperationStatus error = containerVEither.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
+        }
+        GraphVertex containerV = containerVEither.left().value();
+        Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
+        if (capResult.isRight()) {
+            return Either.right(capResult.right().value());
+
+        }
+        Map<String, MapListCapabilityDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
+
+        Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
+        if (capResult.isRight()) {
+            return Either.right(capResult.right().value());
+
+        }
+        Map<String, MapListCapabilityDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
+
+        Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
+        if (reqResult.isRight()) {
+            return Either.right(reqResult.right().value());
+        }
+        Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
+
+        Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
+        if (reqResult.isRight()) {
+            return Either.right(reqResult.right().value());
+        }
+        Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
+
+        Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
+        CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
+
+        StorageOperationStatus status;
+        List<RequirementCapabilityRelDef> relationsList = new ArrayList<>();
+        for (RequirementCapabilityRelDef relation : relations) {
+            List<CapabilityRequirementRelationship> relationshipsResult = new ArrayList<>();
+            String fromNode = relation.getFromNode();
+            String toNode = relation.getToNode();
+            List<CapabilityRequirementRelationship> relationships = relation.getRelationships();
+            if (relationships == null || relationships.isEmpty()) {
+                BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement definition sent in order to set the relation between {} to {}", fromNode, toNode);
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
+            }
+
+            for (CapabilityRequirementRelationship immutablePair : relationships) {
+                String requirement = immutablePair.getRelation().getRequirement();
+
+                Either<Map<JsonPresentationFields, T>, StorageOperationStatus> associateRes = connectInstancesInContainer(fromNode, toNode, immutablePair.getRelation(), relation.isOriginUI(), calculatedCapabilty, calculatedRequirement,
+                        fullFilledCapabilty, fullfilledRequirement, compositionDataDefinition, containerV.getUniqueId());
+
+                if (associateRes.isRight()) {
+                    status = associateRes.right().value();
+                    BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to associate resource instance {} to resource instance {}. status is {}", fromNode, toNode, status);
+                    return Either.right(status);
+                }
+
+                RelationshipInstDataDefinition relationshipInstData = (RelationshipInstDataDefinition) associateRes.left().value().get(JsonPresentationFields.RELATIONSHIP);
+                RelationshipImpl relationshipImplResult = new RelationshipImpl();
+                relationshipImplResult.setType(relationshipInstData.getType());
+                RelationshipInfo requirementAndRelationshipPair = new RelationshipInfo(requirement, relationshipImplResult);
+                requirementAndRelationshipPair.setCapability(immutablePair.getRelation().getCapability());
+                requirementAndRelationshipPair.setRequirement(immutablePair.getRelation().getRequirement());
+                requirementAndRelationshipPair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId());
+                requirementAndRelationshipPair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId());
+                requirementAndRelationshipPair.setCapabilityUid(immutablePair.getRelation().getCapabilityUid());
+                requirementAndRelationshipPair.setRequirementUid(immutablePair.getRelation().getRequirementUid());
+                requirementAndRelationshipPair.setId(relationshipInstData.getUniqueId());
+                CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
+                capReqRel.setRelation(requirementAndRelationshipPair);
+                capReqRel.setCapability((CapabilityDataDefinition) associateRes.left().value().get(JsonPresentationFields.CAPAPILITY));
+                capReqRel.setRequirement((RequirementDataDefinition) associateRes.left().value().get(JsonPresentationFields.REQUIREMENT));
+                relationshipsResult.add(capReqRel);
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "update customization UUID for from CI {} and to CI {}", relation.getFromNode(), relation.getToNode());
+                status = updateCustomizationUUID(relation.getFromNode(), compositionDataDefinition);
+                if (status != StorageOperationStatus.OK) {
+                    return Either.right(status);
+                }
+                status = updateCustomizationUUID(relation.getToNode(), compositionDataDefinition);
+                if (status != StorageOperationStatus.OK) {
+                    return Either.right(status);
+                }
+            }
+            RequirementCapabilityRelDef reqCapRelDef = new RequirementCapabilityRelDef(relation);
+            reqCapRelDef.setRelationships(relationshipsResult);
+            relationsList.add(reqCapRelDef);
+        }
+        // update metadata of container and composition json
+        status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
+        if (status != StorageOperationStatus.OK) {
+            return Either.right(status);
+        }
+
+        return Either.left(relationsList);
+    }
+
+    private StorageOperationStatus updateAllAndCalculatedCapReqOnGraph(String componentId, GraphVertex containerV, Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult,
+            Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult, Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult,
+            Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult) {
+        containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+        Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(containerV);
+        if (updateElement.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update topology template {} with new relations error {}. ", componentId, updateElement.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value());
+        }
+        // update cap/req jsons, fulfilled cap/req jsons!!!!!
+        Either<GraphVertex, TitanOperationStatus> status;
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update calculated capabilty for container {}", containerV.getUniqueId());
+        status = updateOrCopyOnUpdate(capResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
+        if (status.isRight()) {
+            TitanOperationStatus error = status.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update calculated capabilty for container {} error {}", containerV.getUniqueId(), error);
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
+        }
+
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update calculated requirement for container {}", containerV.getUniqueId());
+        status = updateOrCopyOnUpdate(reqResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
+        if (status.isRight()) {
+            TitanOperationStatus error = status.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update calculated requiremnt for container {} error {}", containerV.getUniqueId(), error);
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
+        }
+
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update fullfilled capabilty for container {}", containerV.getUniqueId());
+        status = updateOrCopyOnUpdate(capFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
+        if (status.isRight()) {
+            TitanOperationStatus error = status.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update fullfilled capabilty for container {} error {}", containerV.getUniqueId(), error);
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
+        }
+
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update fullfilled requirement for container {}", containerV.getUniqueId());
+        status = updateOrCopyOnUpdate(reqFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
+        if (status.isRight()) {
+            TitanOperationStatus error = status.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update fullfilled requirement for container {} error {}", containerV.getUniqueId(), error);
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private String buildComponentInstanceName(String instanceSuffixNumber, String instanceName) {
-		return instanceName + " " + (instanceSuffixNumber == null ? 0 : instanceSuffixNumber);
-	}
+    @SuppressWarnings({ "unchecked" })
+    public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId, RequirementCapabilityRelDef requirementDef) {
+        if (requirementDef.getRelationships() == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No relation pair in request [ {} ]", requirementDef);
+            return Either.right(StorageOperationStatus.BAD_REQUEST);
+        }
 
-	public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String componentId, RequirementCapabilityRelDef relation) {
-		List<RequirementCapabilityRelDef> relations = new ArrayList<>();
-		relations.add(relation);
-		Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances = associateResourceInstances(componentId, relations);
-		if (associateResourceInstances.isRight()) {
-			return Either.right(associateResourceInstances.right().value());
-		}
-		return Either.left(associateResourceInstances.left().value().get(0));
-	}
+        String fromResInstanceUid = requirementDef.getFromNode();
+        String toResInstanceUid = requirementDef.getToNode();
 
-	@SuppressWarnings({ "unchecked" })
-	public <T extends ToscaDataDefinition> Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances(String componentId, List<RequirementCapabilityRelDef> relations) {
+        Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
+        if (containerVEither.isRight()) {
+            TitanOperationStatus error = containerVEither.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
+        }
+        GraphVertex containerV = containerVEither.left().value();
 
-		Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
-		if (containerVEither.isRight()) {
-			TitanOperationStatus error = containerVEither.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
-		}
-		GraphVertex containerV = containerVEither.left().value();
-		List<CapabilityRequirementRelationship> relationshipsResult = new ArrayList<>();
-		Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
-		if (capResult.isRight()) {
-			return Either.right(capResult.right().value());
+        // DE191707 - validations
+        Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
+        CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
+        Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
+        ComponentInstanceDataDefinition ciFrom = componentInstances.get(fromResInstanceUid);
+        if (ciFrom == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "FROM instance {} isn't under container {}", fromResInstanceUid, componentId);
+            return Either.right(StorageOperationStatus.NOT_FOUND);
 
-		}
-		Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
+        }
+        ComponentInstanceDataDefinition ciTo = componentInstances.get(toResInstanceUid);
+        if (ciFrom == ciTo) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "TO instance {} isn't under container {}", toResInstanceUid, componentId);
+            return Either.right(StorageOperationStatus.NOT_FOUND);
 
-		Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
-		if (capResult.isRight()) {
-			return Either.right(capResult.right().value());
+        }
+        Map<String, RelationshipInstDataDefinition> relations = compositionDataDefinition.getRelations();
 
-		}
-		Map<String, MapListCapabiltyDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
+        List<CapabilityRequirementRelationship> relationPairList = requirementDef.getRelationships();
+        Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
+        if (capResult.isRight()) {
+            return Either.right(capResult.right().value());
+        }
+        Map<String, MapListCapabilityDataDefinition> calculatedCapability = capResult.left().value().getRight();
 
-		Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
-		if (reqResult.isRight()) {
-			return Either.right(reqResult.right().value());
-		}
-		Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
+        Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
+        if (capResult.isRight()) {
+            return Either.right(capResult.right().value());
 
-		Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
-		if (reqResult.isRight()) {
-			return Either.right(reqResult.right().value());
-		}
-		Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
+        }
+        Map<String, MapListCapabilityDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
 
-		Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
-		CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
+        Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
+        if (reqResult.isRight()) {
+            return Either.right(reqResult.right().value());
+        }
+        Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
 
-		StorageOperationStatus status;
-		List<RequirementCapabilityRelDef> relationsList = new ArrayList<>();
-		for (RequirementCapabilityRelDef relation : relations) {
+        Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
+        if (reqResult.isRight()) {
+            return Either.right(reqResult.right().value());
+        }
+        Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
 
-			String fromNode = relation.getFromNode();
-			String toNode = relation.getToNode();
-			List<CapabilityRequirementRelationship> relationships = relation.getRelationships();
-			if (relationships == null || relationships.isEmpty()) {
-				BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement definition sent in order to set the relation between {} to {}", fromNode, toNode);
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
-			}
+        for (CapabilityRequirementRelationship relationPair : relationPairList) {
+            Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
+            boolean isDeleted = false;
+            while (iterator.hasNext()) {
+                Entry<String, RelationshipInstDataDefinition> entryInJson = iterator.next();
+                RelationshipInstDataDefinition relationInJson = entryInJson.getValue();
+                if (relationInJson.getFromId().equals(fromResInstanceUid) && relationInJson.getToId().equals(toResInstanceUid) && relationInJson.getUniqueId().equals(relationPair.getRelation().getId())) {
+                    if (relationPair.getRelation().equalsTo(relationInJson)) {
+                        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Remove relation from {} to {} capability {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationInJson.getType(), relationInJson.getCapabilityOwnerId(),
+                                relationInJson.getRequirementOwnerId());
+                        iterator.remove();
 
-			for (CapabilityRequirementRelationship immutablePair : relationships) {
-				String requirement = immutablePair.getRelation().getRequirement();
+                        // update calculated cap/req
+                        StorageOperationStatus status = updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapability, fulfilledCapability, toResInstanceUid, relationInJson, relationPair);
+                        if (status != StorageOperationStatus.OK) {
+                            return Either.right(status);
+                        }
+                        status = updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fulfilledRequirement, fromResInstanceUid, relationInJson, relationPair);
+                        if (status != StorageOperationStatus.OK) {
+                            return Either.right(status);
+                        }
+                        isDeleted = true;
+                    }
+                }
+            }
+            if (!isDeleted) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No relation to delete from {} to {} capabilty {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationPair.getCapability(),
+                        relationPair.getRelation().getCapabilityOwnerId(), relationPair.getRelation().getRequirementOwnerId());
+                return Either.right(StorageOperationStatus.NOT_FOUND);
+            }
+        }
+        StorageOperationStatus status = updateCustomizationUUID(fromResInstanceUid, compositionDataDefinition);
+        if (status != StorageOperationStatus.OK) {
+            return Either.right(status);
+        }
+        status = updateCustomizationUUID(toResInstanceUid, compositionDataDefinition);
+        if (status != StorageOperationStatus.OK) {
+            return Either.right(status);
+        }
 
-				Either<Map<JsonPresentationFields, T>, StorageOperationStatus> associateRes = connectInstancesInContainer(fromNode, toNode, immutablePair.getRelation(), calculatedCapabilty, calculatedRequirement, fullFilledCapabilty, fullfilledRequirement,
-						compositionDataDefinition, containerV.getUniqueId());
+        // update jsons
+        // update metadata of container and composition json
+        status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
+        if (status != StorageOperationStatus.OK) {
+            return Either.right(status);
+        }
 
-				if (associateRes.isRight()) {
-					status = associateRes.right().value();
-					BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to associate resource instance {} to resource instance {}. status is {}", fromNode, toNode, status);
-					return Either.right(status);
-				}
+        return Either.left(requirementDef);
+    }
 
-				RelationshipInstDataDefinition relationshipInstData = (RelationshipInstDataDefinition) associateRes.left().value().get(JsonPresentationFields.RELATIONSHIP);
-				RelationshipImpl relationshipImplResult = new RelationshipImpl();
-				relationshipImplResult.setType(relationshipInstData.getType());
-				RelationshipInfo requirementAndRelationshipPair = new RelationshipInfo(requirement, relationshipImplResult);
-				requirementAndRelationshipPair.setCapability(immutablePair.getRelation().getCapability());
-				requirementAndRelationshipPair.setRequirement(immutablePair.getRelation().getRequirement());
-				requirementAndRelationshipPair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId());
-				requirementAndRelationshipPair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId());
-				requirementAndRelationshipPair.setCapabilityUid(immutablePair.getRelation().getCapabilityUid());
-				requirementAndRelationshipPair.setRequirementUid(immutablePair.getRelation().getRequirementUid());
-				requirementAndRelationshipPair.setId(relationshipInstData.getUniqueId());
-				CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
-				capReqRel.setRelation(requirementAndRelationshipPair);
-				capReqRel.setCapability((CapabilityDataDefinition) associateRes.left().value().get(JsonPresentationFields.CAPAPILITY));
-				capReqRel.setRequirement((RequirementDataDefinition) associateRes.left().value().get(JsonPresentationFields.REQUIREMENT));
-				relationshipsResult.add(capReqRel);
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "update customization UUID for from CI {} and to CI {}", relation.getFromNode(), relation.getToNode());
-				status = updateCustomizationUUID(relation.getFromNode(), compositionDataDefinition);
-				if (status != StorageOperationStatus.OK) {
-					return Either.right(status);
-				}
-				status = updateCustomizationUUID(relation.getToNode(), compositionDataDefinition);
-				if (status != StorageOperationStatus.OK) {
-					return Either.right(status);
-				}
-			}
-			RequirementCapabilityRelDef capabilityRelDef = new RequirementCapabilityRelDef();
-			capabilityRelDef.setFromNode(fromNode);
-			capabilityRelDef.setToNode(toNode);
-			capabilityRelDef.setRelationships(relationshipsResult);
-			relationsList.add(capabilityRelDef);
-		}
-		// update metadata of container and composition json
-		status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
-		if (status != StorageOperationStatus.OK) {
-			return Either.right(status);
-		}
+    /**
+     * Retrieves fulfilled requirement according to relation and received predicate
+     * 
+     * @param componentId
+     * @param instanceId
+     * @param foundRelation
+     * @param predicate
+     * @return
+     */
+    public Either<RequirementDataDefinition, StorageOperationStatus> getFulfilledRequirementByRelation(String componentId, String instanceId, RequirementCapabilityRelDef foundRelation,
+            BiPredicate<RelationshipInfo, RequirementDataDefinition> predicate) {
 
-		return Either.left(relationsList);
-	}
+        Either<RequirementDataDefinition, StorageOperationStatus> result = null;
+        Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = null;
+        MapListRequirementDataDefinition reqMapOfLists = null;
+        Optional<RequirementDataDefinition> foundRequirement;
+        RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
+        Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
+        if (containerVEither.isRight()) {
+            TitanOperationStatus error = containerVEither.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
+        }
+        if (result == null) {
+            GraphVertex containerV = containerVEither.left().value();
+            reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
+            if (reqFullResult.isRight()) {
+                result = Either.right(reqFullResult.right().value());
+            }
+        }
+        if (result == null) {
+            Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
+            reqMapOfLists = fulfilledRequirement.get(instanceId);
+            if (reqMapOfLists == null) {
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+            }
+        }
+        if (result == null && reqMapOfLists != null) {
+            for (ListRequirementDataDefinition requirements : reqMapOfLists.getMapToscaDataDefinition().values()) {
+                foundRequirement = requirements.getListToscaDataDefinition().stream().filter(req -> predicate.test(relationshipInfo, req)).findFirst();
+                if (foundRequirement.isPresent()) {
+                    result = Either.left(foundRequirement.get());
+                }
+            }
+        }
+        return result;
+    }
 
-	private StorageOperationStatus updateAllAndCalculatedCapReqOnGraph(String componentId, GraphVertex containerV, Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult,
-			Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult, Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult,
-			Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult) {
-		containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
-		Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(containerV);
-		if (updateElement.isRight()) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new relations error {}. ", componentId, updateElement.right().value());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value());
-		}
-		// update cap/req jsons, fulfilled cap/req jsons!!!!!
-		Either<GraphVertex, TitanOperationStatus> status;
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update calculated capabilty for container {}", containerV.getUniqueId());
-		status = updateOrCopyOnUpdate(capResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
-		if (status.isRight()) {
-			TitanOperationStatus error = status.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update calculated capabilty for container {} error {}", containerV.getUniqueId(), error);
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
-		}
+    /**
+     * Retrieves fulfilled capability according to relation and received predicate
+     * 
+     * @param componentId
+     * @param instanceId
+     * @param foundRelation
+     * @param predicate
+     * @return
+     */
+    public Either<CapabilityDataDefinition, StorageOperationStatus> getFulfilledCapabilityByRelation(String componentId, String instanceId, RequirementCapabilityRelDef foundRelation,
+            BiPredicate<RelationshipInfo, CapabilityDataDefinition> predicate) {
 
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update calculated requirement for container {}", containerV.getUniqueId());
-		status = updateOrCopyOnUpdate(reqResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
-		if (status.isRight()) {
-			TitanOperationStatus error = status.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update calculated requiremnt for container {} error {}", containerV.getUniqueId(), error);
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
-		}
+        Either<CapabilityDataDefinition, StorageOperationStatus> result = null;
+        Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = null;
+        MapListCapabilityDataDefinition capMapOfLists = null;
+        Optional<CapabilityDataDefinition> foundRequirement;
 
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update fullfilled capabilty for container {}", containerV.getUniqueId());
-		status = updateOrCopyOnUpdate(capFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
-		if (status.isRight()) {
-			TitanOperationStatus error = status.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update fullfilled capabilty for container {} error {}", containerV.getUniqueId(), error);
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
-		}
+        RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
+        Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
+        if (containerVEither.isRight()) {
+            TitanOperationStatus error = containerVEither.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
+        }
+        if (result == null) {
+            GraphVertex containerV = containerVEither.left().value();
+            capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
+            if (capFullResult.isRight()) {
+                result = Either.right(capFullResult.right().value());
+            }
+        }
+        if (result == null) {
+            Map<String, MapListCapabilityDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
+            capMapOfLists = fulfilledCapability.get(instanceId);
+            if (capMapOfLists == null) {
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+            }
+        }
+        if (result == null && capMapOfLists != null) {
+            for (ListCapabilityDataDefinition capabilities : capMapOfLists.getMapToscaDataDefinition().values()) {
+                foundRequirement = capabilities.getListToscaDataDefinition().stream().filter(cap -> predicate.test(relationshipInfo, cap)).findFirst();
+                if (foundRequirement.isPresent()) {
+                    result = Either.left(foundRequirement.get());
+                }
+            }
+        }
+        return result;
+    }
 
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update fullfilled requirement for container {}", containerV.getUniqueId());
-		status = updateOrCopyOnUpdate(reqFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
-		if (status.isRight()) {
-			TitanOperationStatus error = status.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update fullfilled requirement for container {} error {}", containerV.getUniqueId(), error);
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
-		}
-		return StorageOperationStatus.OK;
-	}
+    private StorageOperationStatus updateCalculatedRequirementsAfterDeleteRelation(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
+            RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
+        StorageOperationStatus status;
+        String hereIsTheKey = null;
+        MapListRequirementDataDefinition reqByInstance = calculatedRequirement.get(fromResInstanceUid);
+        if (reqByInstance == null || reqByInstance.findKeyByItemUidMatch(relation.getRequirementId()) == null) {
+            // move from fulfilled
+            status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey, relationship);
+        } else {
+            hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
+            ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
+            Optional<RequirementDataDefinition> requirementOptional = reqByType.getListToscaDataDefinition().stream()
+                    .filter(req -> req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())).findFirst();
 
-	@SuppressWarnings({ "unchecked" })
-	public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId, RequirementCapabilityRelDef requirementDef) {
-		if (requirementDef.getRelationships() == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No relation pair in request [ {} ]", requirementDef);
-			return Either.right(StorageOperationStatus.BAD_REQUEST);
-		}
+            if (requirementOptional.isPresent()) {
 
-		String fromResInstanceUid = requirementDef.getFromNode();
-		String toResInstanceUid = requirementDef.getToNode();
+                RequirementDataDefinition requirement = requirementOptional.get();
+                String leftOccurrences = requirement.getLeftOccurrences();
+                if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
+                    Integer leftIntValue = Integer.parseInt(leftOccurrences);
+                    ++leftIntValue;
+                    requirement.setLeftOccurrences(String.valueOf(leftIntValue));
+                }
+                if (relationship != null) {
+                    relationship.setRequirement(requirement);
+                }
+                status = StorageOperationStatus.OK;
+            } else {
+                // move from fulfilled
+                status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey, relationship);
+            }
+        }
+        return status;
+    }
 
-		Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
-		if (containerVEither.isRight()) {
-			TitanOperationStatus error = containerVEither.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
-		}
-		GraphVertex containerV = containerVEither.left().value();
+    private StorageOperationStatus updateCalculatedCapabiltyAfterDeleteRelation(Map<String, MapListCapabilityDataDefinition> calculatedCapability, Map<String, MapListCapabilityDataDefinition> fullFilledCapability, String toResInstanceUid,
+            RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
+        StorageOperationStatus status;
+        String hereIsTheKey = null;
+        MapListCapabilityDataDefinition capByInstance = calculatedCapability.get(toResInstanceUid);
+        if (capByInstance == null || capByInstance.findKeyByItemUidMatch(relation.getCapabilityId()) == null) {
+            // move from fulfilled
+            status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
+        } else {
+            hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
+            ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
+            Optional<CapabilityDataDefinition> capabilityOptional = capByType.getListToscaDataDefinition().stream().filter(cap -> cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId()))
+                    .findFirst();
 
-		// DE191707 - validations
-		Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
-		CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
-		Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
-		ComponentInstanceDataDefinition ciFrom = componentInstances.get(fromResInstanceUid);
-		if (ciFrom == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "FROM instance {} isn't under container {}", fromResInstanceUid, componentId);
-			return Either.right(StorageOperationStatus.NOT_FOUND);
+            if (capabilityOptional.isPresent()) {
 
-		}
-		ComponentInstanceDataDefinition ciTo = componentInstances.get(toResInstanceUid);
-		if (ciFrom == ciTo) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "TO instance {} isn't under container {}", toResInstanceUid, componentId);
-			return Either.right(StorageOperationStatus.NOT_FOUND);
+                CapabilityDataDefinition capability = capabilityOptional.get();
+                String leftOccurrences = capability.getLeftOccurrences();
+                if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
+                    Integer leftIntValue = Integer.parseInt(leftOccurrences);
+                    ++leftIntValue;
+                    capability.setLeftOccurrences(String.valueOf(leftIntValue));
+                }
+                if (relationship != null) {
+                    relationship.setCapability(capability);
+                }
+                status = StorageOperationStatus.OK;
+            } else {
+                // move from fulfilled
+                status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
+            }
+        }
+        return status;
+    }
 
-		}
-		Map<String, RelationshipInstDataDefinition> relations = compositionDataDefinition.getRelations();
+    private StorageOperationStatus moveFromFullFilledCapabilty(Map<String, MapListCapabilityDataDefinition> calculatedCapability, Map<String, MapListCapabilityDataDefinition> fullFilledCapability, String toResInstanceUid,
+            RelationshipInstDataDefinition relation, String hereIsTheKey, CapabilityRequirementRelationship relationship) {
+        MapListCapabilityDataDefinition capByInstance = fullFilledCapability.get(toResInstanceUid);
+        if (capByInstance == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No capability in fulfilled list for instance {} ", toResInstanceUid);
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+        if (null == hereIsTheKey)
+            hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
+        if (null == hereIsTheKey) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No capability with id {} in fulfilled list for instance {} ", relation.getCapabilityId(), toResInstanceUid);
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+        ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
+        Iterator<CapabilityDataDefinition> iterator = capByType.getListToscaDataDefinition().iterator();
+        boolean found = false;
+        while (iterator.hasNext()) {
+            CapabilityDataDefinition cap = iterator.next();
+            if (cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId())) {
+                found = true;
+                iterator.remove();
+                // return to calculated list
+                String leftOccurrences = cap.getLeftOccurrences();
+                Integer leftIntValue = Integer.parseInt(leftOccurrences);
+                ++leftIntValue;
+                cap.setLeftOccurrences(String.valueOf(leftIntValue));
 
-		List<CapabilityRequirementRelationship> relationPairList = requirementDef.getRelationships();
-		Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
-		if (capResult.isRight()) {
-			return Either.right(capResult.right().value());
-		}
-		Map<String, MapListCapabiltyDataDefinition> calculatedCapability = capResult.left().value().getRight();
+                MapListCapabilityDataDefinition mapListCapaDataDef = calculatedCapability.get(toResInstanceUid);
+                if (mapListCapaDataDef == null) {
+                    mapListCapaDataDef = new MapListCapabilityDataDefinition();
+                }
+                ListCapabilityDataDefinition findByKey = mapListCapaDataDef.findByKey(hereIsTheKey);
+                if (findByKey == null) {
+                    findByKey = new ListCapabilityDataDefinition();
+                    mapListCapaDataDef.put(hereIsTheKey, findByKey);
+                }
+                findByKey.add(cap);
+                if (relationship != null)
+                    relationship.setCapability(cap);
+                break;
+            }
+        }
+        if (!found) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No capability type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey, relation.getCapabilityOwnerId(), toResInstanceUid);
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
-		if (capResult.isRight()) {
-			return Either.right(capResult.right().value());
+    private StorageOperationStatus moveFromFullFilledRequirement(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
+            RelationshipInstDataDefinition relation, String hereIsTheKey, CapabilityRequirementRelationship relationship) {
+        MapListRequirementDataDefinition reqByInstance = fullFilledRequirement.get(fromResInstanceUid);
+        if (reqByInstance == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement in fullfilled list for instance {} ", fromResInstanceUid);
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+        if (null == hereIsTheKey)
+            hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
+        if (null == hereIsTheKey) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement with id {} in fulfilled list for instance {} ", relation.getRequirementId(), fromResInstanceUid);
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+        ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
+        Iterator<RequirementDataDefinition> iterator = reqByType.getListToscaDataDefinition().iterator();
+        boolean found = false;
+        while (iterator.hasNext()) {
+            RequirementDataDefinition req = iterator.next();
+            if (req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())) {
+                found = true;
+                iterator.remove();
+                // return to calculated list
+                String leftOccurrences = req.getLeftOccurrences();
+                Integer leftIntValue = Integer.parseInt(leftOccurrences);
+                ++leftIntValue;
+                req.setLeftOccurrences(String.valueOf(leftIntValue));
 
-		}
-		Map<String, MapListCapabiltyDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
+                MapListRequirementDataDefinition mapListReqDataDef = calculatedRequirement.get(fromResInstanceUid);
+                if (mapListReqDataDef == null) {
+                    mapListReqDataDef = new MapListRequirementDataDefinition();
+                }
+                ListRequirementDataDefinition findByKey = mapListReqDataDef.findByKey(hereIsTheKey);
+                if (findByKey == null) {
+                    findByKey = new ListRequirementDataDefinition();
+                    mapListReqDataDef.put(hereIsTheKey, findByKey);
+                }
+                findByKey.add(req);
+                if (relationship != null)
+                    relationship.setRequirement(req);
+                break;
+            }
+        }
+        if (!found) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey, relation.getRequirementOwnerId(), fromResInstanceUid);
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+        return StorageOperationStatus.OK;
 
-		Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
-		if (reqResult.isRight()) {
-			return Either.right(reqResult.right().value());
-		}
-		Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
+    }
 
-		Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
-		if (reqResult.isRight()) {
-			return Either.right(reqResult.right().value());
-		}
-		Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
+    public StorageOperationStatus updateCustomizationUUID(String componentInstanceId, CompositionDataDefinition compositionDataDefinition) {
+        ComponentInstanceDataDefinition componentInstance = compositionDataDefinition.getComponentInstances().get(componentInstanceId);
 
-		for (CapabilityRequirementRelationship relationPair : relationPairList) {
-			Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
-			boolean isDeleted = false;
-			while (iterator.hasNext()) {
-				Entry<String, RelationshipInstDataDefinition> entryInJson = iterator.next();
-				RelationshipInstDataDefinition relationInJson = entryInJson.getValue();
-				if (relationInJson.getFromId().equals(fromResInstanceUid) && relationInJson.getToId().equals(toResInstanceUid) && relationInJson.getUniqueId().equals(relationPair.getRelation().getId())) {
-					if (relationPair.getRelation().equalsTo(relationInJson)) {
-						CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Remove relation from {} to {} capability {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationInJson.getType(),
-								relationInJson.getCapabilityOwnerId(), relationInJson.getRequirementOwnerId());
-						iterator.remove();
+        if (componentInstance == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component instance by id {} from map of instances ", componentInstanceId);
+            return StorageOperationStatus.NOT_FOUND;
+        }
+        UUID uuid = UUID.randomUUID();
+        componentInstance.setCustomizationUUID(uuid.toString());
 
-						// update calculated cap/req
-						StorageOperationStatus status = updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapability, fulfilledCapability, toResInstanceUid, relationInJson, relationPair);
-						if (status != StorageOperationStatus.OK) {
-							return Either.right(status);
-						}
-						status = updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fulfilledRequirement, fromResInstanceUid, relationInJson, relationPair);
-						if (status != StorageOperationStatus.OK) {
-							return Either.right(status);
-						}
-						isDeleted = true;
-					}
-				}
-			}
-			if (!isDeleted) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No relation to delete from {} to {} capabilty {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationPair.getCapability(),
-						relationPair.getRelation().getCapabilityOwnerId(), relationPair.getRelation().getRequirementOwnerId());
-				return Either.right(StorageOperationStatus.NOT_FOUND);
-			}
-		}
-		StorageOperationStatus status = updateCustomizationUUID(fromResInstanceUid, compositionDataDefinition);
-		if (status != StorageOperationStatus.OK) {
-			return Either.right(status);
-		}
-		status = updateCustomizationUUID(toResInstanceUid, compositionDataDefinition);
-		if (status != StorageOperationStatus.OK) {
-			return Either.right(status);
-		}
+        return StorageOperationStatus.OK;
+    }
 
-		// update jsons
-		// update metadata of container and composition json
-		status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
-		if (status != StorageOperationStatus.OK) {
-			return Either.right(status);
-		}
+    public <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectInstancesInContainer(String fromResInstanceUid, String toResInstanceUid, RelationshipInfo relationPair, boolean originUI,
+            Map<String, MapListCapabilityDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabilityDataDefinition> fullfilledCapabilty,
+            Map<String, MapListRequirementDataDefinition> fullfilledRequirement, CompositionDataDefinition compositionDataDefinition, String containerId) {
+        String requirement = relationPair.getRequirement();
+        Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
 
-		return Either.left(requirementDef);
-	}
-	
-	/**
-	 * Retrieves fulfilled requirement according to relation and received predicate
-	 * @param componentId
-	 * @param instanceId
-	 * @param foundRelation
-	 * @param predicate
-	 * @return
-	 */
-	public Either<RequirementDataDefinition, StorageOperationStatus> getFulfilledRequirementByRelation(String componentId, String instanceId, RequirementCapabilityRelDef foundRelation, BiPredicate<RelationshipInfo, RequirementDataDefinition> predicate) {
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Going to associate resource instance {} to resource instance {} under component {}. Requirement is {}.", fromResInstanceUid, toResInstanceUid, containerId, requirement);
 
-		Either<RequirementDataDefinition, StorageOperationStatus> result = null;
-		Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = null;
-		MapListRequirementDataDefinition reqMapOfLists = null;
-		Optional<RequirementDataDefinition> foundRequirement;
-		RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
-		Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
-		if (containerVEither.isRight()) {
-			TitanOperationStatus error = containerVEither.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
-		}
-		if(result == null){
-			GraphVertex containerV = containerVEither.left().value();
-			reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
-			if (reqFullResult.isRight()) {
-				result = Either.right(reqFullResult.right().value());
-			}
-		}
-		if(result == null){
-			Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
-			reqMapOfLists = fulfilledRequirement.get(instanceId);	
-			if(reqMapOfLists == null){
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-			}
-		}
-		if(result == null && reqMapOfLists != null){
-			for(ListRequirementDataDefinition requirements : reqMapOfLists.getMapToscaDataDefinition().values()){
-				foundRequirement = requirements.getListToscaDataDefinition().stream().filter(req -> predicate.test(relationshipInfo, req)).findFirst();
-				if(foundRequirement.isPresent()){
-					result = Either.left(foundRequirement.get());
-				}
-			}
-		}
-		return result;
-	}
-	
-	/**
-	 * Retrieves fulfilled capability according to relation and received predicate
-	 * @param componentId
-	 * @param instanceId
-	 * @param foundRelation
-	 * @param predicate
-	 * @return
-	 */
-	public Either<CapabilityDataDefinition, StorageOperationStatus> getFulfilledCapabilityByRelation(String componentId, String instanceId, RequirementCapabilityRelDef foundRelation, BiPredicate<RelationshipInfo, CapabilityDataDefinition> predicate) {
-		
-		Either<CapabilityDataDefinition, StorageOperationStatus> result = null;
-		Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = null;
-		MapListCapabiltyDataDefinition capMapOfLists = null;
-		Optional<CapabilityDataDefinition> foundRequirement;
-		
-		RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
-		Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
-		if (containerVEither.isRight()) {
-			TitanOperationStatus error = containerVEither.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
-		}
-		if(result == null){
-			GraphVertex containerV = containerVEither.left().value();
-			capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
-			if (capFullResult.isRight()) {
-				result = Either.right(capFullResult.right().value());
-			}
-		}
-		if(result == null){
-			Map<String, MapListCapabiltyDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
-			capMapOfLists = fulfilledCapability.get(instanceId);
-			if(capMapOfLists == null){
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-			}
-		}
-		if(result == null && capMapOfLists != null){
-			for(ListCapabilityDataDefinition capabilities : capMapOfLists.getMapToscaDataDefinition().values()){
-				foundRequirement = capabilities.getListToscaDataDefinition().stream().filter(cap -> predicate.test(relationshipInfo, cap)).findFirst();
-				if(foundRequirement.isPresent()){
-					result = Either.left(foundRequirement.get());
-				}
-			}
-		}
-		return result;
-	}
+        ComponentInstanceDataDefinition fromResourceInstData = componentInstances.get(fromResInstanceUid);
+        if (fromResourceInstData == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find from resource instance {}.", fromResInstanceUid);
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        ComponentInstanceDataDefinition toResourceInstData = componentInstances.get(toResInstanceUid);
+        if (toResourceInstData == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find to resource instance {}.", toResInstanceUid);
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
 
-	private StorageOperationStatus updateCalculatedRequirementsAfterDeleteRelation(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
-			RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
-		StorageOperationStatus status;
-		String hereIsTheKey = null;
-		MapListRequirementDataDefinition reqByInstance = calculatedRequirement.get(fromResInstanceUid);
-		if (reqByInstance == null || reqByInstance.findKeyByItemUidMatch(relation.getRequirementId()) == null) {
-			// move from fulfilled
-			status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey, relationship);
-		} else {
-			hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
-			ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
-			Optional<RequirementDataDefinition> requirementOptional = reqByType.getListToscaDataDefinition().stream()
-					.filter(req -> req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())).findFirst();
+        Either<Map<JsonPresentationFields, T>, StorageOperationStatus> reqVsCap = connectRequirementVsCapability(fromResourceInstData, toResourceInstData, relationPair, originUI, calculatedCapabilty, calculatedRequirement, fullfilledCapabilty,
+                fullfilledRequirement, containerId);
+        if (reqVsCap.isRight()) {
+            StorageOperationStatus status = reqVsCap.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to connect requirement {} between resource instance {} to resource instance {}. status is {}", requirement, fromResInstanceUid, toResInstanceUid, status);
+            return Either.right(status);
+        }
+        Map<JsonPresentationFields, T> relationship = reqVsCap.left().value();
 
-			if (requirementOptional.isPresent()) {
+        // add to json new relations
+        compositionDataDefinition.addRelation(((RelationshipInstDataDefinition) relationship.get(JsonPresentationFields.RELATIONSHIP)).getUniqueId(), (RelationshipInstDataDefinition) relationship.get(JsonPresentationFields.RELATIONSHIP));
 
-				RequirementDataDefinition requirement = requirementOptional.get();
-				String leftOccurrences = requirement.getLeftOccurrences();
-				if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
-					Integer leftIntValue = Integer.parseInt(leftOccurrences);
-					++leftIntValue;
-					requirement.setLeftOccurrences(String.valueOf(leftIntValue));
-				}
-				if(relationship != null){
-					relationship.setRequirement(requirement);
-				}
-				status = StorageOperationStatus.OK;
-			} else {
-				// move from fulfilled
-				status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey, relationship);
-			}
-		}
-		return status;
-	}
+        return Either.left(relationship);
+    }
 
-	private StorageOperationStatus updateCalculatedCapabiltyAfterDeleteRelation(Map<String, MapListCapabiltyDataDefinition> calculatedCapability, Map<String, MapListCapabiltyDataDefinition> fullFilledCapability, String toResInstanceUid,
-			RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
-		StorageOperationStatus status;
-		String hereIsTheKey = null;
-		MapListCapabiltyDataDefinition capByInstance = calculatedCapability.get(toResInstanceUid);
-		if (capByInstance == null || capByInstance.findKeyByItemUidMatch(relation.getCapabilityId()) == null) {
-			// move from fulfilled
-			status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
-		} else {
-			hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
-			ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
-			Optional<CapabilityDataDefinition> capabilityOptional = capByType.getListToscaDataDefinition().stream().filter(cap -> cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId()))
-					.findFirst();
+    private Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedCapability(GraphVertex containerV, EdgeLabelEnum capLabel) {
 
-			if (capabilityOptional.isPresent()) {
+        Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, TitanOperationStatus> calculatedCapabiltyEither = getDataAndVertexFromGraph(containerV, capLabel);
+        if (calculatedCapabiltyEither.isRight()) {
+            TitanOperationStatus error = calculatedCapabiltyEither.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilties for container {}.", containerV.getUniqueId(), error);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
+        }
+        Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>> calculatedCapabilty = calculatedCapabiltyEither.left().value();
+        return Either.left(calculatedCapabilty);
+    }
 
-				CapabilityDataDefinition capability = capabilityOptional.get();
-				String leftOccurrences = capability.getLeftOccurrences();
-				if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
-					Integer leftIntValue = Integer.parseInt(leftOccurrences);
-					++leftIntValue;
-					capability.setLeftOccurrences(String.valueOf(leftIntValue));
-				}
-				if(relationship != null){
-					relationship.setCapability(capability);
-				}
-				status = StorageOperationStatus.OK;
-			} else {
-				// move from fulfilled
-				status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
-			}
-		}
-		return status;
-	}
+    private Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedRequirement(GraphVertex containerV, EdgeLabelEnum reqLabel) {
+        Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, TitanOperationStatus> calculatedRequirementEither = getDataAndVertexFromGraph(containerV, reqLabel);
+        if (calculatedRequirementEither.isRight()) {
+            TitanOperationStatus error = calculatedRequirementEither.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for container {}.", containerV.getUniqueId(), error);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
+        }
+        Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>> calculatedRequirement = calculatedRequirementEither.left().value();
+        return Either.left(calculatedRequirement);
+    }
 
-	private StorageOperationStatus moveFromFullFilledCapabilty(Map<String, MapListCapabiltyDataDefinition> calculatedCapability, Map<String, MapListCapabiltyDataDefinition> fullFilledCapability, String toResInstanceUid,
-			RelationshipInstDataDefinition relation, String hereIsTheKey, CapabilityRequirementRelationship relationship) {
-		MapListCapabiltyDataDefinition capByInstance = fullFilledCapability.get(toResInstanceUid);
-		if (capByInstance == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capability in fulfilled list for instance {} ", toResInstanceUid);
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
-		if (null == hereIsTheKey)
-			hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
-		if (null == hereIsTheKey) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capability with id {} in fulfilled list for instance {} ", relation.getCapabilityId(), toResInstanceUid);
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
-		ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
-		Iterator<CapabilityDataDefinition> iterator = capByType.getListToscaDataDefinition().iterator();
-		boolean found = false;
-		while (iterator.hasNext()) {
-			CapabilityDataDefinition cap = iterator.next();
-			if (cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId())) {
-				found = true;
-				iterator.remove();
-				// return to calculated list
-				String leftOccurrences = cap.getLeftOccurrences();
-				Integer leftIntValue = Integer.parseInt(leftOccurrences);
-				++leftIntValue;
-				cap.setLeftOccurrences(String.valueOf(leftIntValue));
+    @SuppressWarnings("unchecked")
+    private <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectRequirementVsCapability(ComponentInstanceDataDefinition fromResInstance, ComponentInstanceDataDefinition toResInstance,
+            RelationshipInfo relationPair, boolean originUI, Map<String, MapListCapabilityDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement,
+            Map<String, MapListCapabilityDataDefinition> fullfilledCapabilty, Map<String, MapListRequirementDataDefinition> fullfilledRequirement, String containerId) {
+        String type = relationPair.getRelationship().getType();
+        // capability
 
-				MapListCapabiltyDataDefinition mapListCapaDataDef = calculatedCapability.get(toResInstanceUid);
-				if (mapListCapaDataDef == null) {
-					mapListCapaDataDef = new MapListCapabiltyDataDefinition();
-				}
-				ListCapabilityDataDefinition findByKey = mapListCapaDataDef.findByKey(hereIsTheKey);
-				if (findByKey == null) {
-					findByKey = new ListCapabilityDataDefinition();
-					mapListCapaDataDef.put(hereIsTheKey, findByKey);
-				}
-				findByKey.add(cap);
-				if(relationship!= null)
-					relationship.setCapability(cap);
-				break;
-			}
-		}
-		if (found == false) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capability type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey, relation.getCapabilityOwnerId(), toResInstanceUid);
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
-		return StorageOperationStatus.OK;
-	}
+        String toInstId = toResInstance.getUniqueId();
+        MapListCapabilityDataDefinition MapListCapabilityDataDefinition = calculatedCapabilty.get(toInstId);
+        Map<JsonPresentationFields, T> capReqRelationship = new EnumMap<>(JsonPresentationFields.class);
 
-	private StorageOperationStatus moveFromFullFilledRequirement(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
-			RelationshipInstDataDefinition relation, String hereIsTheKey, CapabilityRequirementRelationship relationship) {
-		MapListRequirementDataDefinition reqByInstance = fullFilledRequirement.get(fromResInstanceUid);
-		if (reqByInstance == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement in fullfilled list for instance {} ", fromResInstanceUid);
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
-		if (null == hereIsTheKey)
-			hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
-		if (null == hereIsTheKey) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement with id {} in fulfilled list for instance {} ", relation.getRequirementId(), fromResInstanceUid);
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
-		ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
-		Iterator<RequirementDataDefinition> iterator = reqByType.getListToscaDataDefinition().iterator();
-		boolean found = false;
-		while (iterator.hasNext()) {
-			RequirementDataDefinition req = iterator.next();
-			if (req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())) {
-				found = true;
-				iterator.remove();
-				// return to calculated list
-				String leftOccurrences = req.getLeftOccurrences();
-				Integer leftIntValue = Integer.parseInt(leftOccurrences);
-				++leftIntValue;
-				req.setLeftOccurrences(String.valueOf(leftIntValue));
+        if (MapListCapabilityDataDefinition == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for instance {} in container {}.", toInstId, containerId);
+            return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
+        }
+        ListCapabilityDataDefinition listCapabilityDataDefinition = MapListCapabilityDataDefinition.getMapToscaDataDefinition().get(type);
+        if (listCapabilityDataDefinition == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for type {} for instance {} in container {}.", type, toInstId, containerId);
+            return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
+        }
+        CapabilityDataDefinition capabilityForRelation = null;
+        Iterator<CapabilityDataDefinition> iteratorCap = listCapabilityDataDefinition.getListToscaDataDefinition().iterator();
+        while (iteratorCap.hasNext()) {
+            CapabilityDataDefinition cap = iteratorCap.next();
+            if (cap.getUniqueId().equals(relationPair.getCapabilityUid()) && cap.getOwnerId().equals(relationPair.getCapabilityOwnerId())) {
+                capabilityForRelation = cap;
+                capReqRelationship.put(JsonPresentationFields.CAPAPILITY, (T) capabilityForRelation);
+                String leftOccurrences = cap.getLeftOccurrences();
+                if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
+                    Integer leftIntValue = Integer.parseInt(leftOccurrences);
+                    if (leftIntValue > 0) {
+                        --leftIntValue;
+                        capabilityForRelation.setLeftOccurrences(String.valueOf(leftIntValue));
+                        if (leftIntValue == 0) {
+                            // remove from calculated
+                            iteratorCap.remove();
+                            // move to fulfilled
+                            MapListCapabilityDataDefinition mapListCapabiltyFullFilledInst = fullfilledCapabilty.get(toInstId);
+                            if (mapListCapabiltyFullFilledInst == null) {
+                                mapListCapabiltyFullFilledInst = new MapListCapabilityDataDefinition();
+                                fullfilledCapabilty.put(toInstId, mapListCapabiltyFullFilledInst);
+                            }
 
-				MapListRequirementDataDefinition mapListReqDataDef = calculatedRequirement.get(fromResInstanceUid);
-				if (mapListReqDataDef == null) {
-					mapListReqDataDef = new MapListRequirementDataDefinition();
-				}
-				ListRequirementDataDefinition findByKey = mapListReqDataDef.findByKey(hereIsTheKey);
-				if (findByKey == null) {
-					findByKey = new ListRequirementDataDefinition();
-					mapListReqDataDef.put(hereIsTheKey, findByKey);
-				}
-				findByKey.add(req);
-				if(relationship!= null)
-					relationship.setRequirement(req);
-				break;
-			}
-		}
-		if (found == false) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey, relation.getRequirementOwnerId(), fromResInstanceUid);
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
-		return StorageOperationStatus.OK;
+                            ListCapabilityDataDefinition listCapabilityFull = mapListCapabiltyFullFilledInst.findByKey(type);
+                            if (listCapabilityFull == null) {
+                                listCapabilityFull = new ListCapabilityDataDefinition();
+                                mapListCapabiltyFullFilledInst.put(type, listCapabilityFull);
+                            }
+                            listCapabilityFull.add(capabilityForRelation);
+                        }
+                        break;
+                    } else {
+                        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No left occurrences capabilty {} to {} in container {}.", capabilityForRelation.getType(), toInstId, containerId);
+                        return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
+                    }
+                }
+            }
+        }
+        if (capabilityForRelation == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch capabilty for type {} for instance {} in container {}.", type, toInstId, containerId);
+            return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
+        }
 
-	}
+        // requirements
+        String fromInstId = fromResInstance.getUniqueId();
+        MapListRequirementDataDefinition mapListRequirementDataDefinition = calculatedRequirement.get(fromInstId);
+        if (mapListRequirementDataDefinition == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for instance {} in container {}.", fromInstId, containerId);
+            return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
+        }
+        ListRequirementDataDefinition listRequirementDataDefinition = mapListRequirementDataDefinition.getMapToscaDataDefinition().get(type);
+        if (listRequirementDataDefinition == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for type {} for instance {} in container {}.", type, fromInstId, containerId);
+            return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
+        }
 
-	public StorageOperationStatus updateCustomizationUUID(String componentInstanceId, CompositionDataDefinition compositionDataDefinition) {
-		ComponentInstanceDataDefinition componentInstance = compositionDataDefinition.getComponentInstances().get(componentInstanceId);
+        RequirementDataDefinition requirementForRelation = null;
+        Iterator<RequirementDataDefinition> iteratorReq = listRequirementDataDefinition.getListToscaDataDefinition().iterator();
+        while (iteratorReq.hasNext()) {
+            RequirementDataDefinition req = iteratorReq.next();
+            if (req.getUniqueId().equals(relationPair.getRequirementUid()) && req.getOwnerId().equals(relationPair.getRequirementOwnerId())) {
+                requirementForRelation = req;
+                capReqRelationship.put(JsonPresentationFields.REQUIREMENT, (T) requirementForRelation);
+                String leftOccurrences = req.getLeftOccurrences();
+                if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
+                    Integer leftIntValue = Integer.parseInt(leftOccurrences);
+                    if (leftIntValue > 0) {
+                        --leftIntValue;
+                        req.setLeftOccurrences(String.valueOf(leftIntValue));
+                        if (leftIntValue == 0) {
+                            // remove from calculated
+                            iteratorReq.remove();
+                            // move to fulfilled
+                            MapListRequirementDataDefinition mapListRequirementFullFilledInst = fullfilledRequirement.get(fromInstId);
+                            if (mapListRequirementFullFilledInst == null) {
+                                mapListRequirementFullFilledInst = new MapListRequirementDataDefinition();
+                                fullfilledRequirement.put(fromInstId, mapListRequirementFullFilledInst);
+                            }
 
-		if (componentInstance == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch component instance by id {} from map of instances ", componentInstanceId);
-			return StorageOperationStatus.NOT_FOUND;
-		}
-		UUID uuid = UUID.randomUUID();
-		componentInstance.setCustomizationUUID(uuid.toString());
+                            ListRequirementDataDefinition listRequirementFull = mapListRequirementFullFilledInst.findByKey(type);
+                            if (listRequirementFull == null) {
+                                listRequirementFull = new ListRequirementDataDefinition();
+                                mapListRequirementFullFilledInst.put(type, listRequirementFull);
+                            }
+                            listRequirementFull.add(requirementForRelation);
+                        }
+                        break;
+                    } else {
+                        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No left occurrences requirement {} from {} to {} in container {}.", requirementForRelation.getCapability(), fromInstId, toInstId, containerId);
+                        return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
+                    }
+                }
+            }
+        }
+        if (requirementForRelation == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch requirement for type {} for instance {} in container {}.", type, toInstId, containerId);
+            return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
+        }
+        if (!capabilityForRelation.getType().equals(requirementForRelation.getCapability())) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No macth for capability from type {} and requirement {} from {} to {} in container {}.", capabilityForRelation.getType(), requirementForRelation.getCapability(), fromInstId, toInstId,
+                    containerId);
+            return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
+        }
 
-		return StorageOperationStatus.OK;
-	}
+        RelationshipInstDataDefinition relationshipTypeData = buildRelationshipInstData(fromInstId, toInstId, relationPair, originUI);
+        if (requirementForRelation.getRelationship() != null)
+            relationshipTypeData.setType(requirementForRelation.getRelationship());
+        capReqRelationship.put(JsonPresentationFields.RELATIONSHIP, (T) relationshipTypeData);
+        return Either.left(capReqRelationship);
+    }
 
-	public <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectInstancesInContainer(String fromResInstanceUid, String toResInstanceUid, RelationshipInfo relationPair,
-			Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilty,
-			Map<String, MapListRequirementDataDefinition> fullfilledRequirement, CompositionDataDefinition compositionDataDefinition, String containerId) {
-		String requirement = relationPair.getRequirement();
-		Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
+    private RelationshipInstDataDefinition buildRelationshipInstData(String fromResInstanceUid, String toInstId, RelationshipInfo relationPair, boolean originUI) {
 
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Going to associate resource instance {} to resource instance {} under component {}. Requirement is {}.", fromResInstanceUid, toResInstanceUid, containerId, requirement);
+        RelationshipInstDataDefinition relationshipInstData = new RelationshipInstDataDefinition();
+        relationshipInstData.setUniqueId(UniqueIdBuilder.buildRelationsipInstInstanceUid(fromResInstanceUid, toInstId));
 
-		ComponentInstanceDataDefinition fromResourceInstData = componentInstances.get(fromResInstanceUid);
-		if (fromResourceInstData == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find from resource instance {}.", fromResInstanceUid);
-			return Either.right(StorageOperationStatus.NOT_FOUND);
-		}
-		ComponentInstanceDataDefinition toResourceInstData = componentInstances.get(toResInstanceUid);
-		if (toResourceInstData == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find to resource instance {}.", toResInstanceUid);
-			return Either.right(StorageOperationStatus.NOT_FOUND);
-		}
+        relationshipInstData.setType(relationPair.getRelationship().getType());
+        Long creationDate = System.currentTimeMillis();
+        relationshipInstData.setCreationTime(creationDate);
+        relationshipInstData.setModificationTime(creationDate);
+        relationshipInstData.setCapabilityOwnerId(relationPair.getCapabilityOwnerId());
+        relationshipInstData.setRequirementOwnerId(relationPair.getRequirementOwnerId());
+        relationshipInstData.setCapabilityId(relationPair.getCapabilityUid());
+        relationshipInstData.setRequirementId(relationPair.getRequirementUid());
+        relationshipInstData.setFromId(fromResInstanceUid);
+        relationshipInstData.setToId(toInstId);
+        relationshipInstData.setRequirement(relationPair.getRequirement());
+        relationshipInstData.setCapability(relationPair.getCapability());
+        relationshipInstData.setOriginUI(originUI);
 
-		Either<Map<JsonPresentationFields, T>, StorageOperationStatus> reqVsCap = connectRequirementVsCapability(fromResourceInstData, toResourceInstData, relationPair, calculatedCapabilty, calculatedRequirement, fullfilledCapabilty,
-				fullfilledRequirement, containerId);
-		if (reqVsCap.isRight()) {
-			StorageOperationStatus status = reqVsCap.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to connect requirement {} between resource instance {} to resource instance {}. status is {}", requirement, fromResInstanceUid, toResInstanceUid, status);
-			return Either.right(status);
-		}
-		Map<JsonPresentationFields, T> relationship = reqVsCap.left().value();
+        return relationshipInstData;
+    }
 
-		// add to json new relations
-		compositionDataDefinition.addRelation(((RelationshipInstDataDefinition)relationship.get(JsonPresentationFields.RELATIONSHIP)).getUniqueId(), (RelationshipInstDataDefinition)relationship.get(JsonPresentationFields.RELATIONSHIP));
+    public StorageOperationStatus associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, Resource> resourcesInstancesMap, GraphVertex containerVertex, boolean allowDeleted) {
 
-		return Either.left(relationship);
-	}
+        StorageOperationStatus result = null;
+        String containerId = containerComponent.getUniqueId();
+        Map<String, ComponentInstanceDataDefinition> instancesJsonData = null;
+        Either<GraphVertex, TitanOperationStatus> updateElement = null;
+        if (!validateInstanceNames(resourcesInstancesMap)) {
+            result = StorageOperationStatus.INCONSISTENCY;
+        }
+        if (result == null) {
+            if (!validateInstanceNames(resourcesInstancesMap)) {
+                result = StorageOperationStatus.INCONSISTENCY;
+            }
+        }
+        if (result == null && !allowDeleted) {
+            if (!validateDeletedResources(resourcesInstancesMap)) {
+                result = StorageOperationStatus.INCONSISTENCY;
+            }
+        }
+        if (result == null) {
+            instancesJsonData = convertToComponentInstanceDataDefinition(resourcesInstancesMap, containerId);
+        }
+        if (result == null && MapUtils.isNotEmpty(instancesJsonData)) {
+            containerVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+            Map<String, CompositionDataDefinition> compositions = new HashMap<>();
+            CompositionDataDefinition composition = new CompositionDataDefinition();
+            composition.setComponentInstances(instancesJsonData);
+            compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), composition);
+            containerVertex.setJson(compositions);
+            updateElement = titanDao.updateVertex(containerVertex);
+            if (updateElement.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instances. ", containerComponent.getName());
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value());
+            }
+        }
+        if (result == null && updateElement != null) {
+            GraphVertex vertexC = updateElement.left().value();
+            instancesJsonData.entrySet().forEach(i ->createInstanceEdge(vertexC, i.getValue()));
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-	private Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedCapability(GraphVertex containerV, EdgeLabelEnum capLabel) {
+    private Map<String, ComponentInstanceDataDefinition> convertToComponentInstanceDataDefinition(Map<ComponentInstance, Resource> resourcesInstancesMap, String containerId) {
 
-		Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, TitanOperationStatus> calculatedCapabiltyEither = getDataAndVertexFromGraph(containerV, capLabel);
-		if (calculatedCapabiltyEither.isRight()) {
-			TitanOperationStatus error = calculatedCapabiltyEither.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilties for container {}.", containerV.getUniqueId(), error);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
-		}
-		Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>> calculatedCapabilty = calculatedCapabiltyEither.left().value();
-		return Either.left(calculatedCapabilty);
-	}
+        Map<String, ComponentInstanceDataDefinition> instances = new HashMap<>();
+        for (Entry<ComponentInstance, Resource> entry : resourcesInstancesMap.entrySet()) {
+            ComponentInstanceDataDefinition instance = buildComponentInstanceDataDefinition(entry.getKey(), containerId, null, true, ModelConverter.convertToToscaElement(entry.getValue()));
+            instances.put(instance.getUniqueId(), instance);
+        }
+        return instances;
+    }
 
-	private Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedRequirement(GraphVertex containerV, EdgeLabelEnum reqLabel) {
-		Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, TitanOperationStatus> calculatedRequirementEither = getDataAndVertexFromGraph(containerV, reqLabel);
-		if (calculatedRequirementEither.isRight()) {
-			TitanOperationStatus error = calculatedRequirementEither.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for container {}.", containerV.getUniqueId(), error);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
-		}
-		Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>> calculatedRequirement = calculatedRequirementEither.left().value();
-		return Either.left(calculatedRequirement);
-	}
+    private boolean validateDeletedResources(Map<ComponentInstance, Resource> resourcesInstancesMap) {
+        boolean result = true;
+        for (Resource resource : resourcesInstancesMap.values()) {
+            if (resource.getIsDeleted() != null && resource.getIsDeleted()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance. ", resource.getName());
+                result = false;
+                break;
+            }
+        }
+        return result;
+    }
 
-	@SuppressWarnings("unchecked")
-	private <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectRequirementVsCapability(ComponentInstanceDataDefinition fromResInstance, ComponentInstanceDataDefinition toResInstance, RelationshipInfo relationPair,
-			Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilty,
-			Map<String, MapListRequirementDataDefinition> fullfilledRequirement, String containerId) {
-		String type = relationPair.getRelationship().getType();
-		// capability
+    private boolean validateInstanceNames(Map<ComponentInstance, Resource> resourcesInstancesMap) {
+        boolean result = true;
+        Set<String> names = new HashSet<>();
+        for (ComponentInstance instance : resourcesInstancesMap.keySet()) {
+            if (StringUtils.isEmpty(instance.getName())) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Component instance {} name is empty. Cannot add component instance. ", instance.getUniqueId());
+                result = false;
+                break;
+            } else if (names.contains(instance.getName())) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Component instance with the name {} already exsists. Cannot add component instance. ", instance.getName());
+                result = false;
+                break;
+            } else {
+                names.add(instance.getName());
+            }
+        }
+        return result;
+    }
 
-		String toInstId = toResInstance.getUniqueId();
-		MapListCapabiltyDataDefinition mapListCapabiltyDataDefinition = calculatedCapabilty.get(toInstId);
-		Map<JsonPresentationFields, T> capReqRelationship = new EnumMap<>(JsonPresentationFields.class);
+    public StorageOperationStatus addDeploymentArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
+        return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS);
+    }
 
-		if (mapListCapabiltyDataDefinition == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for instance {} in container {}.", toInstId, containerId);
-			return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
-		}
-		ListCapabilityDataDefinition listCapabilityDataDefinition = mapListCapabiltyDataDefinition.getMapToscaDataDefinition().get(type);
-		if (listCapabilityDataDefinition == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for type {} for instance {} in container {}.", type, toInstId, containerId);
-			return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
-		}
-		CapabilityDataDefinition capabilityForRelation = null;
-		Iterator<CapabilityDataDefinition> iteratorCap = listCapabilityDataDefinition.getListToscaDataDefinition().iterator();
-		while (iteratorCap.hasNext()) {
-			CapabilityDataDefinition cap = iteratorCap.next();
-			if (cap.getUniqueId().equals(relationPair.getCapabilityUid()) && cap.getOwnerId().equals(relationPair.getCapabilityOwnerId())) {
-				capabilityForRelation = cap;
-				capReqRelationship.put(JsonPresentationFields.CAPAPILITY, (T)capabilityForRelation);
-				String leftOccurrences = cap.getLeftOccurrences();
-				if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
-					Integer leftIntValue = Integer.parseInt(leftOccurrences);
-					if (leftIntValue > 0) {
-						--leftIntValue;
-						capabilityForRelation.setLeftOccurrences(String.valueOf(leftIntValue));
-						if (leftIntValue == 0) {
-							// remove from calculated
-							iteratorCap.remove();
-							// move to fulfilled
-							MapListCapabiltyDataDefinition mapListCapabiltyFullFilledInst = fullfilledCapabilty.get(toInstId);
-							if (mapListCapabiltyFullFilledInst == null) {
-								mapListCapabiltyFullFilledInst = new MapListCapabiltyDataDefinition();
-								fullfilledCapabilty.put(toInstId, mapListCapabiltyFullFilledInst);
-							}
+    public StorageOperationStatus addInformationalArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
+        return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INSTANCE_ARTIFACTS, VertexTypeEnum.INSTANCE_ARTIFACTS);
+    }
 
-							ListCapabilityDataDefinition listCapabilityFull = mapListCapabiltyFullFilledInst.findByKey(type);
-							if (listCapabilityFull == null) {
-								listCapabilityFull = new ListCapabilityDataDefinition();
-								mapListCapabiltyFullFilledInst.put(type, listCapabilityFull);
-							}
-							listCapabilityFull.add(capabilityForRelation);
-						}
-						break;
-					} else {
-						CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No left occurrences capabilty {} to {} in container {}.", capabilityForRelation.getType(), toInstId, containerId);
-						return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
-					}
-				}
-			}
-		}
-		if (capabilityForRelation == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch capabilty for type {} for instance {} in container {}.", type, toInstId, containerId);
-			return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
-		}
+    public StorageOperationStatus addArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexType) {
+        Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
+        if (metadataVertex.isRight()) {
+            TitanOperationStatus status = metadataVertex.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(instDeplArtifacts);
+        return addToscaDataDeepElementsBlockToToscaElement(metadataVertex.left().value(), edgeLabel, vertexType, instArtifacts, instanceId);
 
-		// requirements
-		String fromInstId = fromResInstance.getUniqueId();
-		MapListRequirementDataDefinition mapListRequirementDataDefinition = calculatedRequirement.get(fromInstId);
-		if (mapListRequirementDataDefinition == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for instance {} in container {}.", fromInstId, containerId);
-			return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
-		}
-		ListRequirementDataDefinition listRequirementDataDefinition = mapListRequirementDataDefinition.getMapToscaDataDefinition().get(type);
-		if (listRequirementDataDefinition == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for type {} for instance {} in container {}.", type, fromInstId, containerId);
-			return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
-		}
+    }
 
-		RequirementDataDefinition requirementForRelation = null;
-		Iterator<RequirementDataDefinition> iteratorReq = listRequirementDataDefinition.getListToscaDataDefinition().iterator();
-		while (iteratorReq.hasNext()) {
-			RequirementDataDefinition req = iteratorReq.next();
-			if (req.getUniqueId().equals(relationPair.getRequirementUid()) && req.getOwnerId().equals(relationPair.getRequirementOwnerId())) {
-				requirementForRelation = req;
-				capReqRelationship.put(JsonPresentationFields.REQUIREMENT, (T)requirementForRelation);
-				String leftOccurrences = req.getLeftOccurrences();
-				if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
-					Integer leftIntValue = Integer.parseInt(leftOccurrences);
-					if (leftIntValue > 0) {
-						--leftIntValue;
-						req.setLeftOccurrences(String.valueOf(leftIntValue));
-						if (leftIntValue == 0) {
-							// remove from calculated
-							iteratorReq.remove();
-							// move to fulfilled
-							MapListRequirementDataDefinition mapListRequirementFullFilledInst = fullfilledRequirement.get(fromInstId);
-							if (mapListRequirementFullFilledInst == null) {
-								mapListRequirementFullFilledInst = new MapListRequirementDataDefinition();
-								fullfilledRequirement.put(fromInstId, mapListRequirementFullFilledInst);
-							}
+    @SuppressWarnings({ "unchecked" })
+    public StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId) {
+        Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
+        if (metadataVertex.isRight()) {
+            TitanOperationStatus status = metadataVertex.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        GraphVertex metaVertex = metadataVertex.left().value();
+        Map<String, CompositionDataDefinition> json = (Map<String, CompositionDataDefinition>) metaVertex.getJson();
+        CompositionDataDefinition compositionDataDefinition = json.get(JsonConstantKeysEnum.COMPOSITION.getValue());
+        StorageOperationStatus status = updateCustomizationUUID(instanceId, compositionDataDefinition);
+        if (status != StorageOperationStatus.OK) {
+            log.debug("Failed to update customization UUID for instance {} in component {} error {}", instanceId, componentId, status);
+            return status;
+        }
+        Either<GraphVertex, TitanOperationStatus> updateVertex = titanDao.updateVertex(metaVertex);
+        if (updateVertex.isRight()) {
+            log.debug("Failed to update vertex of component {} error {}", componentId, updateVertex.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertex.right().value());
+        }
+        return StorageOperationStatus.OK;
+    }
 
-							ListRequirementDataDefinition listRequirementFull = mapListRequirementFullFilledInst.findByKey(type);
-							if (listRequirementFull == null) {
-								listRequirementFull = new ListRequirementDataDefinition();
-								mapListRequirementFullFilledInst.put(type, listRequirementFull);
-							}
-							listRequirementFull.add(requirementForRelation);
-						}
-						break;
-					} else {
-						CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No left occurrences requirement {} from {} to {} in container {}.", requirementForRelation.getCapability(), fromInstId, toInstId, containerId);
-						return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
-					}
-				}
-			}
-		}
-		if (requirementForRelation == null) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch requirement for type {} for instance {} in container {}.", type, toInstId, containerId);
-			return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
-		}
-		if (!capabilityForRelation.getType().equals(requirementForRelation.getCapability())) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No macth for capability from type {} and requirement {} from {} to {} in container {}.", capabilityForRelation.getType(), requirementForRelation.getCapability(), fromInstId,
-					toInstId, containerId);
-			return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
-		}
+    public StorageOperationStatus generateCustomizationUUIDOnInstanceGroup(String componentId, String instanceId, List<String> groupInstances) {
+        if (groupInstances != null) {
+            Either<Map<String, MapGroupsDataDefinition>, TitanOperationStatus> dataFromGraph = getDataFromGraph(componentId, EdgeLabelEnum.INST_GROUPS);
+            if (dataFromGraph.isRight()) {
+                return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
+            }
+            MapGroupsDataDefinition grInstPerInstance = dataFromGraph.left().value().get(instanceId);
+            if (grInstPerInstance == null) {
+                log.debug("No  instance groups for instance {} in component {}", instanceId, componentId);
+                return StorageOperationStatus.NOT_FOUND;
+            }
+            for (String instGroupForUpdate : groupInstances) {
+                GroupInstanceDataDefinition groupInst = grInstPerInstance.findByKey(instGroupForUpdate);
+                if (groupInst == null) {
+                    log.debug("No group instance {} in group list  for instance {} in component {}", instGroupForUpdate, instanceId, componentId);
+                    continue;
+                }
+                UUID uuid = UUID.randomUUID();
+                groupInst.setCustomizationUUID(uuid.toString());
+            }
 
-		RelationshipInstDataDefinition relationshipTypeData = buildRelationshipInstData(fromInstId, toInstId, relationPair);
-		if(requirementForRelation.getRelationship() != null)
-			relationshipTypeData.setType(requirementForRelation.getRelationship());
-		capReqRelationship.put(JsonPresentationFields.RELATIONSHIP, (T)relationshipTypeData);
-		return Either.left(capReqRelationship);
-	}
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private RelationshipInstDataDefinition buildRelationshipInstData(String fromResInstanceUid, String toInstId, RelationshipInfo relationPair) {
+    public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupInstance> groupInstances) {
 
-		RelationshipInstDataDefinition relationshipInstData = new RelationshipInstDataDefinition();
-		relationshipInstData.setUniqueId(UniqueIdBuilder.buildRelationsipInstInstanceUid(fromResInstanceUid, toInstId));
+        return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS,
+                new MapDataDefinition<>(groupInstances.stream().collect(Collectors.toMap(GroupInstanceDataDefinition::getName, gi -> gi))), componentInstance.getUniqueId());
+    }
 
-		relationshipInstData.setType(relationPair.getRelationship().getType());
-		Long creationDate = System.currentTimeMillis();
-		relationshipInstData.setCreationTime(creationDate);
-		relationshipInstData.setModificationTime(creationDate);
-		relationshipInstData.setCapabilityOwnerId(relationPair.getCapabilityOwnerId());
-		relationshipInstData.setRequirementOwnerId(relationPair.getRequirementOwnerId());
-		relationshipInstData.setCapabilityId(relationPair.getCapabilityUid());
-		relationshipInstData.setRequirementId(relationPair.getRequirementUid());
-		relationshipInstData.setFromId(fromResInstanceUid);
-		relationshipInstData.setToId(toInstId);
-		relationshipInstData.setRequirement(relationPair.getRequirement());
-		relationshipInstData.setCapability(relationPair.getCapability());
+    public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance, Map<String, ArtifactDefinition> deploymentArtifacts) {
 
-		return relationshipInstData;
-	}
+        return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, new MapDataDefinition<>(deploymentArtifacts),
+                componentInstance.getUniqueId());
+    }
 
-	public StorageOperationStatus associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, Resource> resourcesInstancesMap, GraphVertex containerVertex, boolean allowDeleted) {
+    public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
 
-		StorageOperationStatus result = null;
-		String containerId = containerComponent.getUniqueId();
-		Map<String, ComponentInstanceDataDefinition> instancesJsonData = null;
-		Either<GraphVertex, TitanOperationStatus> updateElement = null;
-		if (!validateInstanceNames(resourcesInstancesMap)) {
-			result = StorageOperationStatus.INCONSISTENCY;
-		}
-		if (result == null) {
-			if (!validateInstanceNames(resourcesInstancesMap)) {
-				result = StorageOperationStatus.INCONSISTENCY;
-			}
-		}
-		if (result == null && !allowDeleted) {
-			if (!validateDeletedResources(resourcesInstancesMap)) {
-				result = StorageOperationStatus.INCONSISTENCY;
-			}
-		}
-		if (result == null) {
-			instancesJsonData = convertToComponentInstanceDataDefinition(resourcesInstancesMap, containerId);
-		}
-		if (result == null && MapUtils.isNotEmpty(instancesJsonData)) {
-			containerVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
-			Map<String, CompositionDataDefinition> compositions = new HashMap<>();
-			CompositionDataDefinition composition = new CompositionDataDefinition();
-			composition.setComponentInstances(instancesJsonData);
-			compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), composition);
-			containerVertex.setJson(compositions);
-			updateElement = titanDao.updateVertex(containerVertex);
-			if (updateElement.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instances. ", containerComponent.getName());
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value());
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+        List<String> pathKeys = new ArrayList<>();
+        pathKeys.add(componentInstanceId);
+        return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
+    }
 
-	private Map<String, ComponentInstanceDataDefinition> convertToComponentInstanceDataDefinition(Map<ComponentInstance, Resource> resourcesInstancesMap, String containerId) {
+    public StorageOperationStatus updateComponentInstanceCapabilityProperty(Component containerComponent, String componentInstanceId, String capabilityUniqueId, ComponentInstanceProperty property) {
+        List<String> pathKeys = new ArrayList<>();
+        pathKeys.add(componentInstanceId);
+        pathKeys.add(capabilityUniqueId);
+        return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
+    }
 
-		Map<String, ComponentInstanceDataDefinition> instances = new HashMap<>();
-		for (Entry<ComponentInstance, Resource> entry : resourcesInstancesMap.entrySet()) {
-			ComponentInstanceDataDefinition instance = buildComponentInstanceDataDefinition(entry.getKey(), containerId, null, true, ModelConverter.convertToToscaElement(entry.getValue()));
-			instances.put(instance.getUniqueId(), instance);
-		}
-		return instances;
-	}
+    public StorageOperationStatus overrideComponentCapabilitiesProperties(Component containerComponent, Map<String, MapCapabilityProperty> capabilityPropertyMap) {
+        return overrideToscaDataOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, capabilityPropertyMap);
+    }
 
-	private boolean validateDeletedResources(Map<ComponentInstance, Resource> resourcesInstancesMap) {
-		boolean result = true;
-		for (Resource resource : resourcesInstancesMap.values()) {
-			if (resource.getIsDeleted() != null && resource.getIsDeleted()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance. ", resource.getName());
-				result = false;
-				break;
-			}
-		}
-		return result;
-	}
+    public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
+        List<String> pathKeys = new ArrayList<>();
+        pathKeys.add(componentInstanceId);
+        return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
+    }
 
-	private boolean validateInstanceNames(Map<ComponentInstance, Resource> resourcesInstancesMap) {
-		boolean result = true;
-		Set<String> names = new HashSet<>();
-		for (ComponentInstance instance : resourcesInstancesMap.keySet()) {
-			if (StringUtils.isEmpty(instance.getName())) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component instance {} name is empty. Cannot add component instance. ", instance.getUniqueId());
-				result = false;
-				break;
-			} else if (names.contains(instance.getName())) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component instance with the name {} already exsists. Cannot add component instance. ", instance.getName());
-				result = false;
-				break;
-			} else {
-				names.add(instance.getName());
-			}
-		}
-		return result;
-	}
+    public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId, List<ComponentInstanceProperty> properties) {
+        List<String> pathKeys = new ArrayList<>();
+        pathKeys.add(componentInstanceId);
+        return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, properties, pathKeys, JsonPresentationFields.NAME);
+    }
 
-	public StorageOperationStatus addDeploymentArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
-		return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS);
-	}
+    public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
 
-	public StorageOperationStatus addInformationalArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
-		return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INSTANCE_ARTIFACTS, VertexTypeEnum.INSTANCE_ARTIFACTS);
-	}
+        List<String> pathKeys = new ArrayList<>();
+        pathKeys.add(componentInstanceId);
+        return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
+    }
 
-	public StorageOperationStatus addArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexType) {
-		Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
-		if (metadataVertex.isRight()) {
-			TitanOperationStatus status = metadataVertex.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(instDeplArtifacts);
-		return addToscaDataDeepElementsBlockToToscaElement(metadataVertex.left().value(), edgeLabel, vertexType, instArtifacts, instanceId);
+    public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceInput> properties) {
+        List<String> pathKeys = new ArrayList<>();
+        pathKeys.add(componentInstanceId);
+        return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, properties, pathKeys, JsonPresentationFields.NAME);
+    }
 
-	}
+    public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
+        List<String> pathKeys = new ArrayList<>();
+        pathKeys.add(componentInstanceId);
+        return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
+    }
 
-	@SuppressWarnings({ "unchecked" })
-	public StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId) {
-		Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
-		if (metadataVertex.isRight()) {
-			TitanOperationStatus status = metadataVertex.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		GraphVertex metaVertex = metadataVertex.left().value();
-		Map<String, CompositionDataDefinition> json = (Map<String, CompositionDataDefinition>) metaVertex.getJson();
-		CompositionDataDefinition compositionDataDefinition = json.get(JsonConstantKeysEnum.COMPOSITION.getValue());
-		StorageOperationStatus status = updateCustomizationUUID(instanceId, compositionDataDefinition);
-		if (status != StorageOperationStatus.OK) {
-			logger.debug("Failed to update customization UUID for instance {} in component {} error {}", instanceId, componentId, status);
-			return status;
-		}
-		Either<GraphVertex, TitanOperationStatus> updateVertex = titanDao.updateVertex(metaVertex);
-		if (updateVertex.isRight()) {
-			logger.debug("Failed to update vertex of component {} error {}", componentId, updateVertex.right().value());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertex.right().value());
-		}
-		return StorageOperationStatus.OK;
-	}
+    public StorageOperationStatus createInstanceEdge(GraphVertex metadataVertex, ComponentInstanceDataDefinition componentInstance) {
+        String instUniqueId = componentInstance.getUniqueId();
 
-	public StorageOperationStatus generateCustomizationUUIDOnInstanceGroup(String componentId, String instanceId, List<String> groupInstances) {
-		if (groupInstances != null) {
-			Either<Map<String, MapGroupsDataDefinition>, TitanOperationStatus> dataFromGraph = getDataFromGraph(componentId, EdgeLabelEnum.INST_GROUPS);
-			if (dataFromGraph.isRight()) {
-				return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
-			}
-			MapGroupsDataDefinition grInstPerInstance = dataFromGraph.left().value().get(instanceId);
-			if (grInstPerInstance == null) {
-				logger.debug("No  instance groups for instance {} in component {}", instanceId, componentId);
-				return StorageOperationStatus.NOT_FOUND;
-			}
-			for (String instGroupForUpdate : groupInstances) {
-				GroupInstanceDataDefinition groupInst = grInstPerInstance.findByKey(instGroupForUpdate);
-				if (groupInst == null) {
-					logger.debug("No group instance {} in group list  for instance {} in component {}", instGroupForUpdate, instanceId, componentId);
-					continue;
-				}
-				UUID uuid = UUID.randomUUID();
-				groupInst.setCustomizationUUID(uuid.toString());
-			}
+        // create edge between container and origin ( in case of proxy this edge will be to ProxyService node type)
+        StorageOperationStatus result = createOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.INSTANCE_OF, componentInstance.getComponentUid(), instUniqueId).either(v -> StorageOperationStatus.OK,
+                 DaoStatusConverter::convertTitanStatusToStorageStatus);
 
-		}
-		return StorageOperationStatus.OK;
-	}
+        if (result == StorageOperationStatus.OK && componentInstance.getIsProxy()) {
+                // create edge between container and service origin
+                result = createOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.PROXY_OF, componentInstance.getSourceModelUid(), instUniqueId)
+                        .either(v -> StorageOperationStatus.OK, DaoStatusConverter::convertTitanStatusToStorageStatus);
+        }
+        return result;
+    }
 
-	public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupInstance> groupInstances) {
+    public StorageOperationStatus createAllottedOfEdge(String componentId, String instanceId, String serviceUUID) {
+        Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(componentId);
+        if ( vertexById.isRight() ){
+            log.debug("Failed to fetch component metadata vertex for id {} error {}", componentId, vertexById.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(vertexById.right().value());
+        }
+        GraphVertex metadataVertex = vertexById.left().value(); 
 
-		return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS,
-				new MapDataDefinition<>(groupInstances.stream().collect(Collectors.toMap(gi -> gi.getName(), gi -> gi))), componentInstance.getUniqueId());
-	}
+        EnumMap<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
+        props.put(GraphPropertyEnum.UUID, serviceUUID);
+        props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+  
+        EnumMap<GraphPropertyEnum, Object> hasNot = new EnumMap<>(GraphPropertyEnum.class);
+        hasNot.put(GraphPropertyEnum.IS_DELETED, true);
 
-	public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance, Map<String, ArtifactDefinition> deploymentArtifacts) {
+        Either<List<GraphVertex>, TitanOperationStatus> byCriteria = titanDao.getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, props,hasNot, JsonParseFlagEnum.ParseMetadata );
+        if ( byCriteria.isRight() ){
+            log.debug("Failed to fetch vertex by criteria {} error {}", props, byCriteria.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value());
+        }
+        List<GraphVertex> vertecies = byCriteria.left().value();
+        StorageOperationStatus result = StorageOperationStatus.OK;
+        if ( vertecies != null ){
+            GraphVertex serviceVertex = vertecies.get(0);
+            //remove previous edges
+            
+            log.debug("Try to create or update edge between resource {} and service {} ", metadataVertex, serviceVertex.getUniqueId());
+            // create edge between container and service reference
+            result = createOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.ALLOTTED_OF, serviceVertex.getUniqueId(), instanceId).either(v -> StorageOperationStatus.OK,
+                    DaoStatusConverter::convertTitanStatusToStorageStatus);
+        }
+        return result;
+    }
+    
+    
+    public StorageOperationStatus removeInstanceEdge(GraphVertex metadataVertex, ComponentInstanceDataDefinition componentInstance) {
+        String instUniqueId = componentInstance.getUniqueId();
 
-		return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, new MapDataDefinition<>(deploymentArtifacts),
-				componentInstance.getUniqueId());
-	}
+        // create edge between container and origin ( in case of proxy this edge will be to ProxyService node type)
+        StorageOperationStatus result = removeOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.INSTANCE_OF, componentInstance.getComponentUid(), instUniqueId)
+                .either(v -> StorageOperationStatus.OK,
+                DaoStatusConverter::convertTitanStatusToStorageStatus);
 
-	public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
+        if (componentInstance.getIsProxy()) {
+            // create edge between container and service origin
+            result = removeOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.PROXY_OF, componentInstance.getSourceModelUid(), instUniqueId)
+                    .either(v -> StorageOperationStatus.OK, DaoStatusConverter::convertTitanStatusToStorageStatus);
+        }
+        return result;
+    }
 
-		List<String> pathKeys = new ArrayList<>();
-		pathKeys.add(componentInstanceId);
-		return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
-	}
+    private Either<GraphVertex, TitanOperationStatus> createOrUpdateInstanceEdge(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel, String componentUid, String instUniqueId) {
+        Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
+        properties.put(GraphPropertyEnum.UNIQUE_ID, componentUid);
 
-	public StorageOperationStatus updateComponentInstanceCapabilityProperty(Component containerComponent, String componentInstanceId, String capabilityUniqueId, ComponentInstanceProperty property) {
-		List<String> pathKeys = new ArrayList<>();
-		pathKeys.add(componentInstanceId);
-		pathKeys.add(capabilityUniqueId);
-		return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
-	}
+        return titanDao.getEdgeByChildrenVertexProperties(metadataVertex, edgeLabel, properties)
+                .left()
+                .bind(v -> addInstanceToPropertyOnEdge(instUniqueId, v, metadataVertex))
+                .right()
+                .bind(s -> createInstanceEdge(metadataVertex, edgeLabel, componentUid, instUniqueId, s));
+    }
 
-	public StorageOperationStatus overrideComponentCapabilitiesProperties(Component containerComponent, Map<String, MapCapabiltyProperty> capabilityPropertyMap) {
-		return overrideToscaDataOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, capabilityPropertyMap);
-	}
+    private Either<GraphVertex, TitanOperationStatus> removeOrUpdateInstanceEdge(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel, String componentUid, String instUniqueId) {
+        Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
+        properties.put(GraphPropertyEnum.UNIQUE_ID, componentUid);
 
-	public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
-		List<String> pathKeys = new ArrayList<>();
-		pathKeys.add(componentInstanceId);
-		return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
-	}
+        return titanDao.getEdgeByChildrenVertexProperties(metadataVertex, edgeLabel, properties).left().bind(v -> removeInstanceFromPropertyOnEdge(instUniqueId, v, metadataVertex)).right()
+                .map(err -> removeInstanceEdgeLogError(metadataVertex, edgeLabel, componentUid, err));
+    }
 
-	public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId, List<ComponentInstanceProperty> properties) {
-		List<String> pathKeys = new ArrayList<>();
-		pathKeys.add(componentInstanceId);
-		return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, properties, pathKeys, JsonPresentationFields.NAME);
-	}
+    private Either<GraphVertex, TitanOperationStatus> addInstanceToPropertyOnEdge(String instUniqueId, Edge edge, GraphVertex metadataVertex) {
+        // edge exist need to add instance id to list on edge's property
+        List<String> property = (List<String>) titanDao.getProperty(edge, EdgePropertyEnum.INSTANCES);
+        if (property == null) {
+            property = new ArrayList<>();
+        }
+        Optional<String> findFirst = property.stream().filter(a -> a.equals(instUniqueId)).findFirst();
+        if (!findFirst.isPresent()) {
+            property.add(instUniqueId);
+        }
+        try {
+            String jsonArr = JsonParserUtils.toJson(property);
+            log.debug("Update INSTANCES edge property with value {} ", jsonArr );
+            
+            edge.property(EdgePropertyEnum.INSTANCES.getProperty(), jsonArr);
+        } catch (IOException e) {
+           log.debug("Failed to convert INSTANCES edge property to json for container {}", metadataVertex.getUniqueId(), e );
+           return Either.right(TitanOperationStatus.GENERAL_ERROR);
+        }
+        return Either.left(metadataVertex);
+    }
 
-	public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
+    private Either<GraphVertex, TitanOperationStatus> removeInstanceFromPropertyOnEdge(String instUniqueId, Edge edge, GraphVertex metadataVertex) {
+        // edge exist need to add instance id to list on edge's property
+        List<String> property = (List<String>) titanDao.getProperty(edge, EdgePropertyEnum.INSTANCES);
+        if (property == null) {
+            property = new ArrayList<>();
+        }
+        Optional<String> findFirst = property.stream().filter(a -> a.equals(instUniqueId)).findFirst();
+        if (findFirst.isPresent()) {
+            property.remove(instUniqueId);
+        }
+        if (property.isEmpty()) {
+            // For last instance need to remove edge
+            edge.remove();
+        } else {
+            try {
+                String jsonArr = JsonParserUtils.toJson(property);
+                edge.property(EdgePropertyEnum.INSTANCES.getProperty(), jsonArr);
+            } catch (IOException e) {
+               log.debug("Failed to convert INSTANCES edge property to json for container {}", metadataVertex.getUniqueId(), e );
+               return Either.right(TitanOperationStatus.GENERAL_ERROR);
+            }
+        }
+        return Either.left(metadataVertex);
+    }
 
-		List<String> pathKeys = new ArrayList<>();
-		pathKeys.add(componentInstanceId);
-		return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
-	}
+    private Either<GraphVertex, TitanOperationStatus> createInstanceEdge(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel, String componentUid, String instUniqueId, TitanOperationStatus retrieveEdgeStatus) {
+        if (retrieveEdgeStatus == TitanOperationStatus.NOT_FOUND) {
+            // create new edge
+            Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(componentUid);
+            if (vertexById.isRight()) {
+                return vertexById;
+            }
+            GraphVertex originVertex = vertexById.left().value();
+            Map<EdgePropertyEnum, Object> edgeProps = new EnumMap<>(EdgePropertyEnum.class);
+            List<String> instList = new ArrayList<>();
+            instList.add(instUniqueId);
+            edgeProps.put(EdgePropertyEnum.INSTANCES, instList);
 
-	public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceInput> properties) {
-		List<String> pathKeys = new ArrayList<>();
-		pathKeys.add(componentInstanceId);
-		return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, properties, pathKeys, JsonPresentationFields.NAME);
-	}
+            log.debug("Create new edge {} between {} and {} and properties {} ", edgeLabel, metadataVertex.getUniqueId(), originVertex.getUniqueId(), edgeProps);
+            TitanOperationStatus edgeResult = titanDao.createEdge(metadataVertex, originVertex, edgeLabel, edgeProps);
+            return edgeResult == TitanOperationStatus.OK ? Either.left(metadataVertex) : Either.right(edgeResult);
+        }
+        // error
+        log.debug("Failed to fetch edge with label {} and to vertex with id {} error {} ", edgeLabel, componentUid, retrieveEdgeStatus);
+        return Either.right(retrieveEdgeStatus);
+    }
 
-	public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
-		List<String> pathKeys = new ArrayList<>();
-		pathKeys.add(componentInstanceId);
-		return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
-	}
+    private TitanOperationStatus removeInstanceEdgeLogError(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel, String componentUid, TitanOperationStatus retrieveEdgeStatus) {
+        if (retrieveEdgeStatus == TitanOperationStatus.NOT_FOUND) {
+            log.debug("No edge {} to remove between container {} and origin {}", edgeLabel, metadataVertex.getUniqueId(), componentUid);
+        } else {
+            // error
+            log.debug("Failed to fetch edge with label {} and to vertex with id {} error {} ", edgeLabel, componentUid, retrieveEdgeStatus);
+        }
+        return retrieveEdgeStatus;
+    }
 
+    public void removeAllAllotedEdges(String uniqueId) {
+        Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(uniqueId);
+        if (vertexById.isLeft()) {
+            GraphVertex originVertex = vertexById.left().value();
+            TitanVertex vertex = originVertex.getVertex();
+            Iterator<Edge> edges = vertex.edges(Direction.OUT, EdgeLabelEnum.ALLOTTED_OF.name());
+            while ( edges != null && edges.hasNext() ){
+                Edge edge = edges.next();
+                edge.remove();
+            }
+        }
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTypeOperation.java
index d9318f5..d9ced8c 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTypeOperation.java
@@ -20,17 +20,7 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
+import fj.data.Either;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
@@ -38,12 +28,7 @@
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.*;
 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
@@ -58,921 +43,920 @@
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.beans.factory.annotation.Qualifier;
 
-import fj.data.Either;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 @org.springframework.stereotype.Component("node-type-operation")
 public class NodeTypeOperation extends ToscaElementOperation {
 	public final static Pattern uuidNewVersion = Pattern.compile("^\\d{1,}.1");
 	public final static Pattern uuidNormativeNewVersion = Pattern.compile("^\\d{1,}.0");
+    private static final Logger log = Logger.getLogger(NodeTypeOperation.class);
+    private DerivedNodeTypeResolver derivedResourceResolver;
 
-	private static Logger log = LoggerFactory.getLogger(NodeTypeOperation.class.getName());
+    
+    public NodeTypeOperation(@Qualifier("derived-resource-resolver") DerivedNodeTypeResolver derivedNodeTypeResolver) {
+        this.derivedResourceResolver = derivedNodeTypeResolver;
+    }
 
-	private DerivedNodeTypeResolver derivedResourceResolver;
+    public Either<NodeType, StorageOperationStatus> createNodeType(NodeType nodeType) {
 
-	public NodeTypeOperation(@Qualifier("derived-resource-resolver") DerivedNodeTypeResolver derivedNodeTypeResolver) {
-		this.derivedResourceResolver = derivedNodeTypeResolver;
-	}
+        Either<NodeType, StorageOperationStatus> result = null;
 
-	public Either<NodeType, StorageOperationStatus> createNodeType(NodeType nodeType) {
-
-		Either<NodeType, StorageOperationStatus> result = null;
-
-		nodeType.generateUUID();
+        nodeType.generateUUID();
 
 		//Set missing props such as names, default lifecycle state, dates etc...
-		nodeType = getResourceMetaDataFromResource(nodeType);
+        nodeType = getResourceMetaDataFromResource(nodeType);
 
 		//Set unique ID
-		String resourceUniqueId = nodeType.getUniqueId();
-		if (resourceUniqueId == null) {
-			resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
-			nodeType.setUniqueId(resourceUniqueId);
-		}
+        String resourceUniqueId = nodeType.getUniqueId();
+        if (resourceUniqueId == null) {
+            resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
+            nodeType.setUniqueId(resourceUniqueId);
+        }
 
-		// get derived from resources
-		List<GraphVertex> derivedResources = null;
-		Either<List<GraphVertex>, StorageOperationStatus> derivedResourcesResult = findDerivedResources(nodeType);
-		if (derivedResourcesResult.isRight()) {
-			result = Either.right(derivedResourcesResult.right().value());
-			return result;
-		} else {
-			derivedResources = derivedResourcesResult.left().value();
-		}
+        // get derived from resources
+        List<GraphVertex> derivedResources = null;
+        Either<List<GraphVertex>, StorageOperationStatus> derivedResourcesResult = findDerivedResources(nodeType);
+        if (derivedResourcesResult.isRight()) {
+            result = Either.right(derivedResourcesResult.right().value());
+            return result;
+        } else {
+            derivedResources = derivedResourcesResult.left().value();
+        }
 
 		//Create Vertext Object and fill according to given NodeType
-		GraphVertex nodeTypeVertex = new GraphVertex(VertexTypeEnum.NODE_TYPE);
-		fillToscaElementVertexData(nodeTypeVertex, nodeType, JsonParseFlagEnum.ParseAll);
+        GraphVertex nodeTypeVertex = new GraphVertex(VertexTypeEnum.NODE_TYPE);
+        fillToscaElementVertexData(nodeTypeVertex, nodeType, JsonParseFlagEnum.ParseAll);
 
 		//Create Node Type in Graph
-		Either<GraphVertex, TitanOperationStatus> createdVertex = titanDao.createVertex(nodeTypeVertex);
-		if (createdVertex.isRight()) {
-			TitanOperationStatus status = createdVertex.right().value();
-			log.error("Error returned after creating resource data node {}. status returned is ", nodeTypeVertex, status);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			return result;
-		}
-		nodeTypeVertex = createdVertex.left().value();
+        Either<GraphVertex, TitanOperationStatus> createdVertex = titanDao.createVertex(nodeTypeVertex);
+        if (createdVertex.isRight()) {
+            TitanOperationStatus status = createdVertex.right().value();
+            log.error("Error returned after creating resource data node {}. status returned is ", nodeTypeVertex, status);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            return result;
+        }
+        nodeTypeVertex = createdVertex.left().value();
 
-		StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(nodeTypeVertex, nodeType, derivedResources);
-		if (assosiateCommon != StorageOperationStatus.OK) {
-			result = Either.right(assosiateCommon);
-			return result;
-		}
+        StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(nodeTypeVertex, nodeType, derivedResources);
+        if (assosiateCommon != StorageOperationStatus.OK) {
+            result = Either.right(assosiateCommon);
+            return result;
+        }
 
-		StorageOperationStatus associateDerived = assosiateToDerived(nodeTypeVertex, derivedResources);
-		if (associateDerived != StorageOperationStatus.OK) {
-			result = Either.right(associateDerived);
-			return result;
-		}
-		StorageOperationStatus associateCategory = assosiateResourceMetadataToCategory(nodeTypeVertex, nodeType);
-		if (associateCategory != StorageOperationStatus.OK) {
-			result = Either.right(associateCategory);
-			return result;
-		}
+        StorageOperationStatus associateDerived = assosiateToDerived(nodeTypeVertex, derivedResources);
+        if (associateDerived != StorageOperationStatus.OK) {
+            result = Either.right(associateDerived);
+            return result;
+        }
+        StorageOperationStatus associateCategory = assosiateResourceMetadataToCategory(nodeTypeVertex, nodeType);
+        if (associateCategory != StorageOperationStatus.OK) {
+            result = Either.right(associateCategory);
+            return result;
+        }
 
-		StorageOperationStatus associateAttributes = associateAttributesToResource(nodeTypeVertex, nodeType, derivedResources);
-		if (associateAttributes != StorageOperationStatus.OK) {
-			result = Either.right(associateAttributes);
-			return result;
-		}
+        StorageOperationStatus associateAttributes = associateAttributesToResource(nodeTypeVertex, nodeType, derivedResources);
+        if (associateAttributes != StorageOperationStatus.OK) {
+            result = Either.right(associateAttributes);
+            return result;
+        }
 
-		StorageOperationStatus associateRequirements = associateRequirementsToResource(nodeTypeVertex, nodeType, derivedResources);
-		if (associateRequirements != StorageOperationStatus.OK) {
-			result = Either.right(associateRequirements);
-			return result;
-		}
+        StorageOperationStatus associateRequirements = associateRequirementsToResource(nodeTypeVertex, nodeType, derivedResources);
+        if (associateRequirements != StorageOperationStatus.OK) {
+            result = Either.right(associateRequirements);
+            return result;
+        }
 
-		StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(nodeTypeVertex, nodeType, derivedResources);
-		if (associateCapabilities != StorageOperationStatus.OK) {
-			result = Either.right(associateCapabilities);
-			return result;
-		}
-		StorageOperationStatus associateCapabilitiesProps = associateCapabilitiesPropertiesToResource(nodeTypeVertex, nodeType, derivedResources);
-		if (associateCapabilitiesProps != StorageOperationStatus.OK) {
-			result = Either.right(associateCapabilitiesProps);
-			return result;
-		}
+        StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(nodeTypeVertex, nodeType, derivedResources);
+        if (associateCapabilities != StorageOperationStatus.OK) {
+            result = Either.right(associateCapabilities);
+            return result;
+        }
+        StorageOperationStatus associateCapabilitiesProps = associateCapabilitiesPropertiesToResource(nodeTypeVertex, nodeType, derivedResources);
+        if (associateCapabilitiesProps != StorageOperationStatus.OK) {
+            result = Either.right(associateCapabilitiesProps);
+            return result;
+        }
 
-		StorageOperationStatus associateInterfaces = associateInterfacesToResource(nodeTypeVertex, nodeType, derivedResources);
-		if (associateInterfaces != StorageOperationStatus.OK) {
-			result = Either.right(associateInterfaces);
-			return result;
-		}
+        StorageOperationStatus associateInterfaces = associateInterfacesToResource(nodeTypeVertex, nodeType, derivedResources);
+        if (associateInterfaces != StorageOperationStatus.OK) {
+            result = Either.right(associateInterfaces);
+            return result;
+        }
 
-		StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(nodeTypeVertex, nodeType, derivedResources);
-		if (addAdditionalInformation != StorageOperationStatus.OK) {
-			result = Either.right(addAdditionalInformation);
-			return result;
-		}
-		result = Either.left(nodeType);
-		return result;
+        StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(nodeTypeVertex, nodeType, derivedResources);
+        if (addAdditionalInformation != StorageOperationStatus.OK) {
+            result = Either.right(addAdditionalInformation);
+            return result;
+        }
+        result = Either.left(nodeType);
+        return result;
 
-	}
+    }
 
-	private StorageOperationStatus associateInterfacesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
-		// Note : currently only one derived supported!!!!
-		Either<Map<String, InterfaceDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.INTERFACE_ARTIFACTS);
-		if (dataFromDerived.isRight()) {
-			return dataFromDerived.right().value();
-		}
-		Map<String, InterfaceDataDefinition> interfacArtsAll = dataFromDerived.left().value();
+    private StorageOperationStatus associateInterfacesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
+        // Note : currently only one derived supported!!!!
+        Either<Map<String, InterfaceDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.INTERFACE_ARTIFACTS);
+        if (dataFromDerived.isRight()) {
+            return dataFromDerived.right().value();
+        }
+        Map<String, InterfaceDataDefinition> interfacArtsAll = dataFromDerived.left().value();
 
-		Map<String, InterfaceDataDefinition> interfacArts = nodeType.getInterfaceArtifacts();
-		if (interfacArts != null) {
-			interfacArtsAll.putAll(interfacArts);
-		}
-		if (!interfacArtsAll.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfacArtsAll);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+        Map<String, InterfaceDataDefinition> interfacArts = nodeType.getInterfaceArtifacts();
+        if (interfacArts != null) {
+            interfacArtsAll.putAll(interfacArts);
+        }
+        if (!interfacArtsAll.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfacArtsAll);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	@Override
-	public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
+    @Override
+    public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
 
-		Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.NodeType, JsonParseFlagEnum.ParseMetadata);
-		if (componentByLabelAndId.isRight()) {
-			return Either.right(componentByLabelAndId.right().value());
-		}
-		GraphVertex componentV = componentByLabelAndId.left().value();
+        Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata);
+        if (componentByLabelAndId.isRight()) {
+            return Either.right(componentByLabelAndId.right().value());
+        }
+        GraphVertex componentV = componentByLabelAndId.left().value();
 
-		return getToscaElement(componentV, componentParametersView);
+        return getToscaElement(componentV, componentParametersView);
 
-	}
+    }
 
-	// -------------------------------------------------------------
-	@Override
-	public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
-		NodeType toscaElement;
-		toscaElement = convertToComponent(componentV);
-		TitanOperationStatus status = null;
-		if (false == componentParametersView.isIgnoreUsers()) {
-			status = setCreatorFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
+    // -------------------------------------------------------------
+    @Override
+    public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
+        NodeType toscaElement;
+        toscaElement = convertToComponent(componentV);
+        TitanOperationStatus status = null;
+        if (!componentParametersView.isIgnoreUsers()) {
+            status = setCreatorFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
 
-			status = setLastModifierFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
+            status = setLastModifierFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
 
-		if (false == componentParametersView.isIgnoreProperties()) {
-			status = setResourcePropertiesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
+        if (!componentParametersView.isIgnoreProperties()) {
+            status = setResourcePropertiesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
 
-		if (false == componentParametersView.isIgnoreAttributesFrom()) {
-			status = setResourceAttributesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
+        if (!componentParametersView.isIgnoreAttributesFrom()) {
+            status = setResourceAttributesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
 
-		if (false == componentParametersView.isIgnoreDerivedFrom()) {
-			status = setResourceDerivedFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
+        if (!componentParametersView.isIgnoreDerivedFrom()) {
+            status = setResourceDerivedFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
 
-		if (false == componentParametersView.isIgnoreCategories()) {
-			status = setResourceCategoryFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (false == componentParametersView.isIgnoreRequirements()) {
-			status = setResourceRequirementsFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				log.error("Failed to set requirement of resource {}. status is {}", componentV.getUniqueId(), status);
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (false == componentParametersView.isIgnoreCapabilities()) {
-			status = setResourceCapabilitiesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
+        if (!componentParametersView.isIgnoreCategories()) {
+            status = setResourceCategoryFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (!componentParametersView.isIgnoreRequirements()) {
+            status = setResourceRequirementsFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                log.error("Failed to set requirement of resource {}. status is {}", componentV.getUniqueId(), status);
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (!componentParametersView.isIgnoreCapabilities()) {
+            status = setResourceCapabilitiesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
 
-		if (false == componentParametersView.isIgnoreArtifacts()) {
-			status = setArtifactsFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (false == componentParametersView.isIgnoreAdditionalInformation()) {
-			status = setAdditionalInformationFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (false == componentParametersView.isIgnoreInterfaces()) {
-			status = setInterfacesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (false == componentParametersView.isIgnoreAllVersions()) {
-			status = setAllVersions(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
+        if (!componentParametersView.isIgnoreArtifacts()) {
+            status = setArtifactsFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (!componentParametersView.isIgnoreAdditionalInformation()) {
+            status = setAdditionalInformationFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (!componentParametersView.isIgnoreInterfaces()) {
+            status = setInterfacesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (!componentParametersView.isIgnoreAllVersions()) {
+            status = setAllVersions(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
 
-		if (false == componentParametersView.isIgnoreCapabiltyProperties()) {
-			status = setComponentCapPropertiesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        if (!componentParametersView.isIgnoreCapabiltyProperties()) {
+            status = setComponentCapPropertiesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
 
-			}
-		}
-		return Either.left(toscaElement);
-	}
+            }
+        }
+        return Either.left(toscaElement);
+    }
 
-	private TitanOperationStatus setComponentCapPropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
-		Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
-		if (result.isLeft()) {
-			toscaElement.setCapabiltiesProperties(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setComponentCapPropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
+        Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
+        if (result.isLeft()) {
+            toscaElement.setCapabiltiesProperties(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private TitanOperationStatus setInterfacesFromGraph(GraphVertex componentV, NodeType toscaElement) {
-		Either<Map<String, InterfaceDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INTERFACE_ARTIFACTS);
-		if (result.isLeft()) {
-			toscaElement.setInterfaceArtifacts(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setInterfacesFromGraph(GraphVertex componentV, NodeType toscaElement) {
+        Either<Map<String, InterfaceDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INTERFACE_ARTIFACTS);
+        if (result.isLeft()) {
+            toscaElement.setInterfaceArtifacts(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	protected <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
-		return setResourceCapabilitiesFromGraph(componentV, (NodeType) toscaElement);
-	}
+    protected <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
+        return setResourceCapabilitiesFromGraph(componentV, (NodeType) toscaElement);
+    }
 
-	private TitanOperationStatus setResourceCapabilitiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
-		Either<Map<String, ListCapabilityDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
-		if (result.isLeft()) {
-			toscaElement.setCapabilties(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setResourceCapabilitiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
+        Either<Map<String, ListCapabilityDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
+        if (result.isLeft()) {
+            toscaElement.setCapabilties(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private TitanOperationStatus setResourceDerivedFromGraph(GraphVertex componentV, NodeType toscaElement) {
-		List<String> derivedFromList = new ArrayList<String>();
+    private TitanOperationStatus setResourceDerivedFromGraph(GraphVertex componentV, NodeType toscaElement) {
+        List<String> derivedFromList = new ArrayList<>();
 
-		TitanOperationStatus listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList);
-		if (TitanOperationStatus.OK != listFromGraphStatus) {
-			return listFromGraphStatus;
-		}
+        TitanOperationStatus listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList);
+        if (TitanOperationStatus.OK != listFromGraphStatus) {
+            return listFromGraphStatus;
+        }
 
-		if (false == derivedFromList.isEmpty()) {
-			if (derivedFromList.size() > 1) {
-				List<String> lastDerivedFrom = new ArrayList<String>();
-				lastDerivedFrom.add(derivedFromList.get(1));
-				toscaElement.setDerivedFrom(lastDerivedFrom);
-				toscaElement.setDerivedList(derivedFromList);
-			} else {
-				toscaElement.setDerivedFrom(null);
-				toscaElement.setDerivedList(derivedFromList);
-			}
+        if (!derivedFromList.isEmpty()) {
+            if (derivedFromList.size() > 1) {
+                List<String> lastDerivedFrom = new ArrayList<>();
+                lastDerivedFrom.add(derivedFromList.get(1));
+                toscaElement.setDerivedFrom(lastDerivedFrom);
+                toscaElement.setDerivedList(derivedFromList);
+            } else {
+                toscaElement.setDerivedFrom(null);
+                toscaElement.setDerivedList(derivedFromList);
+            }
 
-		}
-		return TitanOperationStatus.OK;
-	}
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	protected TitanOperationStatus findResourcesPathRecursively(GraphVertex nodeTypeV, List<String> resourcesPathList) {
-		Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
-		resourcesPathList.add((String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
-		while (parentResourceRes.isLeft()) {
+    protected TitanOperationStatus findResourcesPathRecursively(GraphVertex nodeTypeV, List<String> resourcesPathList) {
+        Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
+        resourcesPathList.add((String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
+        while (parentResourceRes.isLeft()) {
 
-			GraphVertex parent = parentResourceRes.left().value();
-			resourcesPathList.add((String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
-			parentResourceRes = titanDao.getChildVertex(parent, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
-		}
-		TitanOperationStatus operationStatus = parentResourceRes.right().value();
+            GraphVertex parent = parentResourceRes.left().value();
+            resourcesPathList.add((String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
+            parentResourceRes = titanDao.getChildVertex(parent, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
+        }
+        TitanOperationStatus operationStatus = parentResourceRes.right().value();
 
-		if (operationStatus != TitanOperationStatus.NOT_FOUND) {
-			return operationStatus;
-		} else {
-			return TitanOperationStatus.OK;
-		}
+        if (operationStatus != TitanOperationStatus.NOT_FOUND) {
+            return operationStatus;
+        } else {
+            return TitanOperationStatus.OK;
+        }
 
-	}
+    }
 
-	protected <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
-		return setResourceRequirementsFromGraph(componentV, (NodeType) toscaElement);
-	}
+    protected <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
+        return setResourceRequirementsFromGraph(componentV, (NodeType) toscaElement);
+    }
 
-	private TitanOperationStatus setResourceRequirementsFromGraph(GraphVertex componentV, NodeType toscaElement) {
-		Either<Map<String, ListRequirementDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.REQUIREMENTS);
-		if (result.isLeft()) {
-			toscaElement.setRequirements(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setResourceRequirementsFromGraph(GraphVertex componentV, NodeType toscaElement) {
+        Either<Map<String, ListRequirementDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.REQUIREMENTS);
+        if (result.isLeft()) {
+            toscaElement.setRequirements(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private TitanOperationStatus setResourceAttributesFromGraph(GraphVertex componentV, NodeType toscaElement) {
-		Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ATTRIBUTES);
-		if (result.isLeft()) {
-			toscaElement.setAttributes(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setResourceAttributesFromGraph(GraphVertex componentV, NodeType toscaElement) {
+        Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ATTRIBUTES);
+        if (result.isLeft()) {
+            toscaElement.setAttributes(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private TitanOperationStatus setResourcePropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
-		Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
-		if (result.isLeft()) {
-			toscaElement.setProperties(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setResourcePropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
+        Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
+        if (result.isLeft()) {
+            toscaElement.setProperties(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private StorageOperationStatus assosiateToDerived(GraphVertex nodeTypeVertex, List<GraphVertex> derivedResources) {
-		for (GraphVertex derivedV : derivedResources) {
-			TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, derivedV, EdgeLabelEnum.DERIVED_FROM, null);
-			if (createEdge != TitanOperationStatus.OK) {
-				log.trace("Failed to associate resource {} to derived with id {}", nodeTypeVertex.getUniqueId(), derivedV.getUniqueId());
-				return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    private StorageOperationStatus assosiateToDerived(GraphVertex nodeTypeVertex, List<GraphVertex> derivedResources) {
+        for (GraphVertex derivedV : derivedResources) {
+            TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, derivedV, EdgeLabelEnum.DERIVED_FROM, null);
+            if (createEdge != TitanOperationStatus.OK) {
+                log.trace("Failed to associate resource {} to derived with id {}", nodeTypeVertex.getUniqueId(), derivedV.getUniqueId());
+                return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
-		// Note : currently only one derived supported!!!!
-		Either<Map<String, AdditionalInfoParameterDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ADDITIONAL_INFORMATION);
-		if (dataFromDerived.isRight()) {
-			return dataFromDerived.right().value();
-		}
-		Map<String, AdditionalInfoParameterDataDefinition> addInformationAll = dataFromDerived.left().value();
+    private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
+        // Note : currently only one derived supported!!!!
+        Either<Map<String, AdditionalInfoParameterDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ADDITIONAL_INFORMATION);
+        if (dataFromDerived.isRight()) {
+            return dataFromDerived.right().value();
+        }
+        Map<String, AdditionalInfoParameterDataDefinition> addInformationAll = dataFromDerived.left().value();
 
-		Map<String, AdditionalInfoParameterDataDefinition> addInformation = nodeType.getAdditionalInformation();
-		if (addInformation != null) {
-			ToscaDataDefinition.mergeDataMaps(addInformationAll, addInformation);
-		}
-		if (!addInformationAll.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformationAll);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+        Map<String, AdditionalInfoParameterDataDefinition> addInformation = nodeType.getAdditionalInformation();
+        if (addInformation != null) {
+            ToscaDataDefinition.mergeDataMaps(addInformationAll, addInformation);
+        }
+        if (!addInformationAll.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformationAll);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
-		// Note : currently only one derived supported!!!!
-		Either<Map<String, ListCapabilityDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES);
-		if (dataFromDerived.isRight()) {
-			return dataFromDerived.right().value();
-		}
-		Map<String, ListCapabilityDataDefinition> capabiltiesAll = dataFromDerived.left().value();
+    private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
+        // Note : currently only one derived supported!!!!
+        Either<Map<String, ListCapabilityDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES);
+        if (dataFromDerived.isRight()) {
+            return dataFromDerived.right().value();
+        }
+        Map<String, ListCapabilityDataDefinition> capabiltiesAll = dataFromDerived.left().value();
 
-		Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilties();
-		if (capabilties != null) {
-			if (capabiltiesAll == null) {
-				capabiltiesAll = new HashMap<>();
-			}
-			capabilties.values().forEach(l -> {
-				l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
-					String uid = UniqueIdBuilder.buildCapabilityUid(nodeTypeVertex.getUniqueId(), p.getName());
-					p.setUniqueId(uid);
-				});
-			});
+        Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilties();
+        if (capabilties != null) {
+            if (capabiltiesAll == null) {
+                capabiltiesAll = new HashMap<>();
+            }
+            capabilties.values().forEach(l -> {
+                l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
+                    String uid = UniqueIdBuilder.buildCapabilityUid(nodeTypeVertex.getUniqueId(), p.getName());
+                    p.setUniqueId(uid);
+                });
+            });
 
-			ToscaDataDefinition.mergeDataMaps(capabiltiesAll, capabilties);
-			capabiltiesAll.values().forEach(l -> {
-				l.getListToscaDataDefinition().forEach(c -> {
-					List<String> capabilitySources = c.getCapabilitySources();
-					if (capabilitySources == null) {
-						capabilitySources = new ArrayList<>();
-					}
-					capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
-					c.setCapabilitySources(capabilitySources);
-				});
-			});
-		}
-		capabiltiesAll.values().forEach(l -> {
-			l.getListToscaDataDefinition().forEach(c -> {
-				List<String> capabilitySources = c.getCapabilitySources();
-				if (capabilitySources == null) {
-					capabilitySources = new ArrayList<>();
-				}
-				capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
-				c.setCapabilitySources(capabilitySources);
-			});
-		});
-		if (!capabiltiesAll.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILTIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+            ToscaDataDefinition.mergeDataMaps(capabiltiesAll, capabilties);
+            capabiltiesAll.values().forEach(l -> {
+                l.getListToscaDataDefinition().forEach(c -> {
+                    List<String> capabilitySources = c.getCapabilitySources();
+                    if (capabilitySources == null) {
+                        capabilitySources = new ArrayList<>();
+                    }
+                    capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
+                    c.setCapabilitySources(capabilitySources);
+                });
+            });
+        }
+        capabiltiesAll.values().forEach(l -> {
+            l.getListToscaDataDefinition().forEach(c -> {
+                List<String> capabilitySources = c.getCapabilitySources();
+                if (capabilitySources == null) {
+                    capabilitySources = new ArrayList<>();
+                }
+                capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
+                c.setCapabilitySources(capabilitySources);
+            });
+        });
+        if (!capabiltiesAll.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILTIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
-		// Note : currently only one derived supported!!!!
-		Either<Map<String, ListRequirementDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.REQUIREMENTS);
-		if (dataFromDerived.isRight()) {
-			return dataFromDerived.right().value();
-		}
-		Map<String, ListRequirementDataDefinition> requirementsAll = dataFromDerived.left().value();
+    private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
+        // Note : currently only one derived supported!!!!
+        Either<Map<String, ListRequirementDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.REQUIREMENTS);
+        if (dataFromDerived.isRight()) {
+            return dataFromDerived.right().value();
+        }
+        Map<String, ListRequirementDataDefinition> requirementsAll = dataFromDerived.left().value();
 
-		Map<String, ListRequirementDataDefinition> requirements = nodeType.getRequirements();
-		if (requirements != null) {
-			if (requirementsAll == null) {
-				requirementsAll = new HashMap<>();
-			}
-			requirements.values().forEach(l -> {
-				l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
-					String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
-					p.setUniqueId(uid);
-				});
-			});
+        Map<String, ListRequirementDataDefinition> requirements = nodeType.getRequirements();
+        if (requirements != null) {
+            if (requirementsAll == null) {
+                requirementsAll = new HashMap<>();
+            }
+            requirements.values().forEach(l -> {
+                l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
+                    String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
+                    p.setUniqueId(uid);
+                });
+            });
 
-			ToscaDataDefinition.mergeDataMaps(requirementsAll, requirements);
+            ToscaDataDefinition.mergeDataMaps(requirementsAll, requirements);
 
-		}
-		if (!requirementsAll.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.REQUIREMENTS, EdgeLabelEnum.REQUIREMENTS, requirementsAll);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+        }
+        if (!requirementsAll.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.REQUIREMENTS, EdgeLabelEnum.REQUIREMENTS, requirementsAll);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private StorageOperationStatus associateAttributesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
-		// Note : currently only one derived supported!!!!
-		Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ATTRIBUTES);
-		if (dataFromDerived.isRight()) {
-			return dataFromDerived.right().value();
-		}
-		Map<String, PropertyDataDefinition> attributesAll = dataFromDerived.left().value();
+    private StorageOperationStatus associateAttributesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
+        // Note : currently only one derived supported!!!!
+        Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ATTRIBUTES);
+        if (dataFromDerived.isRight()) {
+            return dataFromDerived.right().value();
+        }
+        Map<String, PropertyDataDefinition> attributesAll = dataFromDerived.left().value();
 
-		Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
-		if (attributes != null) {
-			attributes.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
-				String uid = UniqueIdBuilder.buildAttributeUid(nodeTypeVertex.getUniqueId(), p.getName());
-				p.setUniqueId(uid);
-			});
-			ToscaDataDefinition.mergeDataMaps(attributesAll, attributes);
-		}
-		if (!attributesAll.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ATTRIBUTES, EdgeLabelEnum.ATTRIBUTES, attributesAll);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+        Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
+        if (attributes != null) {
+            attributes.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
+                String uid = UniqueIdBuilder.buildAttributeUid(nodeTypeVertex.getUniqueId(), p.getName());
+                p.setUniqueId(uid);
+            });
+            ToscaDataDefinition.mergeDataMaps(attributesAll, attributes);
+        }
+        if (!attributesAll.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.ATTRIBUTES, EdgeLabelEnum.ATTRIBUTES, attributesAll);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	// TODO get from derived
-	private StorageOperationStatus associateCapabilitiesPropertiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
-		// // Note : currently only one derived supported!!!!
-		Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
-		if (dataFromDerived.isRight()) {
-			return dataFromDerived.right().value();
-		}
-		Map<String, MapPropertiesDataDefinition> propertiesAll = dataFromDerived.left().value();
-		Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabiltiesProperties();
-		if (capabiltiesProps != null) {
-			capabiltiesProps.values().forEach(l -> {
-				if (l.getMapToscaDataDefinition() != null && l.getMapToscaDataDefinition().values() != null) {
-					Collection<PropertyDataDefinition> mapToscaDataDefinition = l.getMapToscaDataDefinition().values();
-					mapToscaDataDefinition.stream().filter(p -> p != null && p.getUniqueId() == null).forEach(p -> {
-						String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
-						p.setUniqueId(uid);
-					});
-				}
-			});
-			ToscaDataDefinition.mergeDataMaps(propertiesAll, capabiltiesProps);
-		}
-		if (!propertiesAll.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, propertiesAll);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    // TODO get from derived
+    private StorageOperationStatus associateCapabilitiesPropertiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
+        // // Note : currently only one derived supported!!!!
+        Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
+        if (dataFromDerived.isRight()) {
+            return dataFromDerived.right().value();
+        }
+        Map<String, MapPropertiesDataDefinition> propertiesAll = dataFromDerived.left().value();
+        Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabiltiesProperties();
+        if (capabiltiesProps != null) {
+            capabiltiesProps.values().forEach(l -> {
+                if (l.getMapToscaDataDefinition() != null && l.getMapToscaDataDefinition().values() != null) {
+                    Collection<PropertyDataDefinition> mapToscaDataDefinition = l.getMapToscaDataDefinition().values();
+                    mapToscaDataDefinition.stream().filter(p -> p != null && p.getUniqueId() == null).forEach(p -> {
+                        String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
+                        p.setUniqueId(uid);
+                    });
+                }
+            });
+            ToscaDataDefinition.mergeDataMaps(propertiesAll, capabiltiesProps);
+        }
+        if (!propertiesAll.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, propertiesAll);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	public Either<List<GraphVertex>, StorageOperationStatus> findDerivedResources(NodeType nodeType) {
+    public Either<List<GraphVertex>, StorageOperationStatus> findDerivedResources(NodeType nodeType) {
 
-		List<GraphVertex> derivedResources = new ArrayList<GraphVertex>();
-		List<String> derivedFromResources = nodeType.getDerivedFrom();
-		if (derivedFromResources != null && false == derivedFromResources.isEmpty()) {
+        List<GraphVertex> derivedResources = new ArrayList<>();
+        List<String> derivedFromResources = nodeType.getDerivedFrom();
+        if (derivedFromResources != null && !derivedFromResources.isEmpty()) {
 
-			for (String parentResource : derivedFromResources) {
-				Either<List<GraphVertex>, TitanOperationStatus> getParentResources = derivedResourceResolver.findDerivedResources(parentResource);
-				List<GraphVertex> resources = null;
-				if (getParentResources.isRight()) {
-					log.error("Cannot find parent resource by tosca resource name {} in the graph.", parentResource);
-					return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
+            for (String parentResource : derivedFromResources) {
+                Either<List<GraphVertex>, TitanOperationStatus> getParentResources = derivedResourceResolver.findDerivedResources(parentResource);
+                List<GraphVertex> resources = null;
+                if (getParentResources.isRight()) {
+                    log.error("Cannot find parent resource by tosca resource name {} in the graph.", parentResource);
+                    return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
 
-				} else {
-					resources = getParentResources.left().value();
-					if (resources == null || resources.size() == 0) {
-						log.error("Cannot find parent resource by tosca name {} in the graph. resources size is empty", parentResource);
-						return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
-					} else {
-						if (resources.size() > 1) {
-							return handleMultipleParent(parentResource, derivedResources, resources);
-						} else {
-							GraphVertex parentResourceData = resources.get(0);
-							derivedResources.add(parentResourceData);
-						}
-					}
+                } else {
+                    resources = getParentResources.left().value();
+                    if (resources == null || resources.size() == 0) {
+                        log.error("Cannot find parent resource by tosca name {} in the graph. resources size is empty", parentResource);
+                        return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
+                    } else {
+                        if (resources.size() > 1) {
+                            return handleMultipleParent(parentResource, derivedResources, resources);
+                        } else {
+                            GraphVertex parentResourceData = resources.get(0);
+                            derivedResources.add(parentResourceData);
+                        }
+                    }
 
-				}
+                }
 
-			}
-		}
-		return Either.left(derivedResources);
-	}
+            }
+        }
+        return Either.left(derivedResources);
+    }
 
-	Either<List<GraphVertex>, StorageOperationStatus> handleMultipleParent(String parentResource, List<GraphVertex> derivedResource, List<GraphVertex> fetchedDerivedResources) {
+    Either<List<GraphVertex>, StorageOperationStatus> handleMultipleParent(String parentResource, List<GraphVertex> derivedResource, List<GraphVertex> fetchedDerivedResources) {
 
-		Either<List<GraphVertex>, StorageOperationStatus> result = Either.left(derivedResource);
-		try {
-			fetchedDerivedResources.sort((d1, d2) -> {
-				return new Double(Double.parseDouble((String) d1.getMetadataProperty(GraphPropertyEnum.VERSION))).compareTo(Double.parseDouble((String) d2.getMetadataProperty(GraphPropertyEnum.VERSION)));
-			});
+        Either<List<GraphVertex>, StorageOperationStatus> result = Either.left(derivedResource);
+        try {
+            fetchedDerivedResources.sort((d1, d2) -> {
+                return new Double(Double.parseDouble((String) d1.getMetadataProperty(GraphPropertyEnum.VERSION))).compareTo(Double.parseDouble((String) d2.getMetadataProperty(GraphPropertyEnum.VERSION)));
+            });
 
-			int actualHighestIndex = fetchedDerivedResources.size() - 1;
-			derivedResource.add(fetchedDerivedResources.get(actualHighestIndex));
-			fetchedDerivedResources.remove(actualHighestIndex);
+            int actualHighestIndex = fetchedDerivedResources.size() - 1;
+            derivedResource.add(fetchedDerivedResources.get(actualHighestIndex));
+            fetchedDerivedResources.remove(actualHighestIndex);
 
-			StorageOperationStatus status = fixMultipleParent(fetchedDerivedResources);
-			if (status != StorageOperationStatus.OK) {
-				result = Either.right(status);
-			}
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during handle multiple parent {}. Exception is  {}", parentResource, e.getMessage());
-			result = Either.right(StorageOperationStatus.GENERAL_ERROR);
-		}
-		return result;
-	}
+            StorageOperationStatus status = fixMultipleParent(fetchedDerivedResources);
+            if (status != StorageOperationStatus.OK) {
+                result = Either.right(status);
+            }
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during handle multiple parent {}. Exception is  {}", parentResource, e.getMessage());
+            result = Either.right(StorageOperationStatus.GENERAL_ERROR);
+        }
+        return result;
+    }
 
-	private StorageOperationStatus fixMultipleParent(List<GraphVertex> fetchedDerivedResources) {
-		StorageOperationStatus result = StorageOperationStatus.OK;
-		for (GraphVertex fetchedDerivedResource : fetchedDerivedResources) {
-			fetchedDerivedResource.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
-			Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(fetchedDerivedResource);
-			if (updateVertexRes.isRight()) {
-				TitanOperationStatus titatStatus = updateVertexRes.right().value();
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of node type {} to false. Status is  {}", fetchedDerivedResource.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME), titatStatus);
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus);
-				break;
-			}
-		}
-		return result;
-	}
+    private StorageOperationStatus fixMultipleParent(List<GraphVertex> fetchedDerivedResources) {
+        StorageOperationStatus result = StorageOperationStatus.OK;
+        for (GraphVertex fetchedDerivedResource : fetchedDerivedResources) {
+            fetchedDerivedResource.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
+            Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(fetchedDerivedResource);
+            if (updateVertexRes.isRight()) {
+                TitanOperationStatus titatStatus = updateVertexRes.right().value();
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of node type {} to false. Status is  {}", fetchedDerivedResource.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME), titatStatus);
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus);
+                break;
+            }
+        }
+        return result;
+    }
 
-	private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, NodeType nodeType) {
-		nodeTypeVertex.setLabel(VertexTypeEnum.NODE_TYPE);
+    private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, NodeType nodeType) {
+        nodeTypeVertex.setLabel(VertexTypeEnum.NODE_TYPE);
 
-		fillCommonMetadata(nodeTypeVertex, nodeType);
+        fillCommonMetadata(nodeTypeVertex, nodeType);
 
-		return nodeTypeVertex;
-	}
+        return nodeTypeVertex;
+    }
 
-	@Override
-	public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
-		Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
-		if (nodeType.isRight()) {
-			log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
-			return nodeType;
-		}
-		TitanOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
-		if (status != TitanOperationStatus.OK) {
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate capabilties for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate capabilties properties for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INTERFACE_ARTIFACTS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate interface artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		toscaElementVertex.getVertex().remove();
-		log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
+    @Override
+    public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
+        Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
+        if (nodeType.isRight()) {
+            log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
+            return nodeType;
+        }
+        TitanOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
+        if (status != TitanOperationStatus.OK) {
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate capabilties for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate capabilties properties for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INTERFACE_ARTIFACTS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate interface artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        toscaElementVertex.getVertex().remove();
+        log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
 
-		return nodeType;
-	}
+        return nodeType;
+    }
 
-	@SuppressWarnings("unchecked")
-	@Override
-	public Either<NodeType, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
-		return createNodeType((NodeType) toscaElement);
-	}
+    @SuppressWarnings("unchecked")
+    @Override
+    public Either<NodeType, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
+        return createNodeType((NodeType) toscaElement);
+    }
 
-	@Override
-	protected <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
-		return setResourceCategoryFromGraph(vertexComponent, toscaElement);
-	}
+    @Override
+    protected <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
+        return setResourceCategoryFromGraph(vertexComponent, toscaElement);
+    }
 
-	@Override
-	protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
-		return validateResourceCategory(toscaElementToUpdate, elementV);
-	}
+    @Override
+    protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
+        return validateResourceCategory(toscaElementToUpdate, elementV);
+    }
 
-	@Override
-	protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV) {
+    @Override
+    protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV) {
 
-		NodeType nodeType = (NodeType) toscaElementToUpdate;
-		List<GraphVertex> derivedResources = new ArrayList<>();
+        NodeType nodeType = (NodeType) toscaElementToUpdate;
 
-		List<String> derivedFromResources = nodeType.getDerivedFrom();
+        List<String> derivedFromResources = nodeType.getDerivedFrom();
 
-		// now supported only single derived from
-		if (derivedFromResources != null && !derivedFromResources.isEmpty() && derivedFromResources.get(0) != null) {
-			String firstDerived = derivedFromResources.get(0);
-			boolean derivedFromGenericType = null != nodeType.getDerivedFromGenericType();
-			Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
-			if (childVertex.isRight()) {
-				TitanOperationStatus getchieldError = childVertex.right().value();
-				log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchieldError);
-				return DaoStatusConverter.convertTitanStatusToStorageStatus(getchieldError);
-			}
-			GraphVertex firstDerivedInChain = childVertex.left().value();
+        // now supported only single derived from
+        if (derivedFromResources != null && !derivedFromResources.isEmpty() && derivedFromResources.get(0) != null) {
+            String firstDerived = derivedFromResources.get(0);
+            boolean derivedFromGenericType = null != nodeType.getDerivedFromGenericType();
+            Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
+            if (childVertex.isRight()) {
+                TitanOperationStatus getchieldError = childVertex.right().value();
+                log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchieldError);
+                return DaoStatusConverter.convertTitanStatusToStorageStatus(getchieldError);
+            }
+            GraphVertex firstDerivedInChain = childVertex.left().value();
 
-			String firstCurrentDerived = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME);
-			if (!firstDerived.equals(firstCurrentDerived) || derivedFromGenericType) {
+            String firstCurrentDerived = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME);
+            if (!firstDerived.equals(firstCurrentDerived) || derivedFromGenericType) {
 
-				Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
-				propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
+                Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
+                propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
 
-				propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, firstDerived);
-				propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+                propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, firstDerived);
+                propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
 
-				Either<List<GraphVertex>, TitanOperationStatus> getParentResources = titanDao.getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.NoParse);
+                Either<List<GraphVertex>, TitanOperationStatus> getParentResources = titanDao.getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.NoParse);
 
-				if (getParentResources.isRight()) {
-					TitanOperationStatus error = getParentResources.right().value();
-					CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch derived by criteria {}. error {} ", propertiesToMatch, error);
-					return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
-				}
-				// must be only one
-				GraphVertex newDerivedV = getParentResources.left().value().get(0);
-				return updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, newDerivedV, false);
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+                if (getParentResources.isRight()) {
+                    TitanOperationStatus error = getParentResources.right().value();
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch derived by criteria {}. error {} ", propertiesToMatch, error);
+                    return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
+                }
+                // must be only one
+                GraphVertex newDerivedV = getParentResources.left().value().get(0);
+                return updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, newDerivedV, false);
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	/**
-	 * 
-	 * @param toscaElementToUpdate
-	 * @param nodeTypeV
-	 * @param preDerivedV
-	 * @param newDerivedV
-	 * @param mergeValues
-	 * @return
-	 */
-	protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV, GraphVertex preDerivedV, GraphVertex newDerivedV, boolean mergeValues) {
-		Set<String> preDerivedChainIdList = new HashSet();
-		preDerivedChainIdList.add(preDerivedV.getUniqueId());
-		Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(preDerivedV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
-		while (childVertex.isLeft()) {
-			GraphVertex currentChield = childVertex.left().value();
-			preDerivedChainIdList.add(currentChield.getUniqueId());
-			childVertex = titanDao.getChildVertex(currentChield, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
-		}
+    /**
+     *
+     * @param toscaElementToUpdate
+     * @param nodeTypeV
+     * @param preDerivedV
+     * @param newDerivedV
+     * @param mergeValues
+     * @return
+     */
+    protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV, GraphVertex preDerivedV, GraphVertex newDerivedV, boolean mergeValues) {
+        Set<String> preDerivedChainIdList = new HashSet();
+        preDerivedChainIdList.add(preDerivedV.getUniqueId());
+        Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(preDerivedV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
+        while (childVertex.isLeft()) {
+            GraphVertex currentChield = childVertex.left().value();
+            preDerivedChainIdList.add(currentChield.getUniqueId());
+            childVertex = titanDao.getChildVertex(currentChield, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
+        }
 
-		List<GraphVertex> derivedResources = new ArrayList<>();
-		derivedResources.add(newDerivedV);
-		StorageOperationStatus updateStatus = updateDataFromNewDerived(derivedResources, nodeTypeV, (NodeType) toscaElementToUpdate, mergeValues, preDerivedChainIdList);
-		if (updateStatus != StorageOperationStatus.OK) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update data for {} from new derived {} ", nodeTypeV.getUniqueId(), newDerivedV.getUniqueId(), updateStatus);
-			return updateStatus;
-		}
+        List<GraphVertex> derivedResources = new ArrayList<>();
+        derivedResources.add(newDerivedV);
+        StorageOperationStatus updateStatus = updateDataFromNewDerived(derivedResources, nodeTypeV, (NodeType) toscaElementToUpdate, mergeValues, preDerivedChainIdList);
+        if (updateStatus != StorageOperationStatus.OK) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update data for {} from new derived {} ", nodeTypeV.getUniqueId(), newDerivedV.getUniqueId(), updateStatus);
+            return updateStatus;
+        }
 
-		Either<Edge, TitanOperationStatus> deleteEdge = titanDao.deleteEdge(nodeTypeV, preDerivedV, EdgeLabelEnum.DERIVED_FROM);
-		if (deleteEdge.isRight()) {
-			TitanOperationStatus deleteError = deleteEdge.right().value();
-			log.debug("Failed to disassociate element {} from derived {} , error {}", nodeTypeV.getUniqueId(), preDerivedV.getUniqueId(), deleteError);
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteError);
-		}
+        Either<Edge, TitanOperationStatus> deleteEdge = titanDao.deleteEdge(nodeTypeV, preDerivedV, EdgeLabelEnum.DERIVED_FROM);
+        if (deleteEdge.isRight()) {
+            TitanOperationStatus deleteError = deleteEdge.right().value();
+            log.debug("Failed to disassociate element {} from derived {} , error {}", nodeTypeV.getUniqueId(), preDerivedV.getUniqueId(), deleteError);
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteError);
+        }
 
-		titanDao.createEdge(nodeTypeV, newDerivedV, EdgeLabelEnum.DERIVED_FROM, new HashMap<>());
+        titanDao.createEdge(nodeTypeV, newDerivedV, EdgeLabelEnum.DERIVED_FROM, new HashMap<>());
 
-		return StorageOperationStatus.OK;
-	}
+        return StorageOperationStatus.OK;
+    }
 
-	private StorageOperationStatus associateDerivedDataByType(EdgeLabelEnum edgeLabel, GraphVertex nodeTypeV, NodeType nodeToUpdate, List<GraphVertex> newDerived) {
+    private StorageOperationStatus associateDerivedDataByType(EdgeLabelEnum edgeLabel, GraphVertex nodeTypeV, NodeType nodeToUpdate, List<GraphVertex> newDerived) {
 
-		switch (edgeLabel) {
-		case CAPABILITIES:
-			return associateCapabilitiesToResource(nodeTypeV, nodeToUpdate, newDerived);
-		case REQUIREMENTS:
-			return associateRequirementsToResource(nodeTypeV, nodeToUpdate, newDerived);
-		case PROPERTIES:
-			return associatePropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
-		case ATTRIBUTES:
-			return associateAttributesToResource(nodeTypeV, nodeToUpdate, newDerived);
-		case ADDITIONAL_INFORMATION:
-			return addAdditionalInformationToResource(nodeTypeV, nodeToUpdate, newDerived);
-		case CAPABILITIES_PROPERTIES:
-			return associateCapabilitiesPropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
-		default:
-			return StorageOperationStatus.OK;
-		}
+        switch (edgeLabel) {
+        case CAPABILITIES:
+            return associateCapabilitiesToResource(nodeTypeV, nodeToUpdate, newDerived);
+        case REQUIREMENTS:
+            return associateRequirementsToResource(nodeTypeV, nodeToUpdate, newDerived);
+        case PROPERTIES:
+            return associatePropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
+        case ATTRIBUTES:
+            return associateAttributesToResource(nodeTypeV, nodeToUpdate, newDerived);
+        case ADDITIONAL_INFORMATION:
+            return addAdditionalInformationToResource(nodeTypeV, nodeToUpdate, newDerived);
+        case CAPABILITIES_PROPERTIES:
+            return associateCapabilitiesPropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
+        default:
+            return StorageOperationStatus.OK;
+        }
 
-	}
+    }
 
-	private StorageOperationStatus updateDataFromNewDerived(List<GraphVertex> newDerived, GraphVertex nodeTypeV, NodeType nodeToUpdate, boolean mergeValues, Set<String> preDerivedChainIdList) {
-		EnumSet<EdgeLabelEnum> edgeLabels = EnumSet.of(EdgeLabelEnum.CAPABILITIES, EdgeLabelEnum.REQUIREMENTS, EdgeLabelEnum.PROPERTIES, EdgeLabelEnum.ATTRIBUTES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.ADDITIONAL_INFORMATION);
-		StorageOperationStatus status = null;
-		for (EdgeLabelEnum edge : edgeLabels) {
-			status = updateDataByType(newDerived, nodeTypeV, edge, nodeToUpdate, mergeValues, preDerivedChainIdList);
-			if (status != StorageOperationStatus.OK) {
-				break;
-			}
-		}
-		return status;
+    private StorageOperationStatus updateDataFromNewDerived(List<GraphVertex> newDerived, GraphVertex nodeTypeV, NodeType nodeToUpdate, boolean mergeValues, Set<String> preDerivedChainIdList) {
+        EnumSet<EdgeLabelEnum> edgeLabels = EnumSet.of(EdgeLabelEnum.CAPABILITIES, EdgeLabelEnum.REQUIREMENTS, EdgeLabelEnum.PROPERTIES, EdgeLabelEnum.ATTRIBUTES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.ADDITIONAL_INFORMATION);
+        StorageOperationStatus status = null;
+        for (EdgeLabelEnum edge : edgeLabels) {
+            status = updateDataByType(newDerived, nodeTypeV, edge, nodeToUpdate, mergeValues, preDerivedChainIdList);
+            if (status != StorageOperationStatus.OK) {
+                break;
+            }
+        }
+        return status;
 
-	}
+    }
 
-	private <T extends ToscaDataDefinition> StorageOperationStatus updateDataByType(List<GraphVertex> newDerivedList, GraphVertex nodeTypeV, EdgeLabelEnum label, NodeType nodeElement, boolean mergeValues, Set<String> preDerivedChainIdList) {
-		log.debug("Update data from derived for element {} type {}", nodeTypeV.getUniqueId(), label);
-		Either<GraphVertex, TitanOperationStatus> dataFromGraph = getDataVertex(nodeTypeV, label);
-		if (dataFromGraph.isRight()) {
-			if (TitanOperationStatus.NOT_FOUND == dataFromGraph.right().value())
-				return associateDerivedDataByType(label, nodeTypeV, nodeElement, newDerivedList);
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
-		}
-		GraphVertex dataV = dataFromGraph.left().value();
+    private <T extends ToscaDataDefinition> StorageOperationStatus updateDataByType(List<GraphVertex> newDerivedList, GraphVertex nodeTypeV, EdgeLabelEnum label, NodeType nodeElement, boolean mergeValues, Set<String> preDerivedChainIdList) {
+        log.debug("Update data from derived for element {} type {}", nodeTypeV.getUniqueId(), label);
+        Either<GraphVertex, TitanOperationStatus> dataFromGraph = getDataVertex(nodeTypeV, label);
+        if (dataFromGraph.isRight()) {
+            if (TitanOperationStatus.NOT_FOUND == dataFromGraph.right().value())
+                return associateDerivedDataByType(label, nodeTypeV, nodeElement, newDerivedList);
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
+        }
+        GraphVertex dataV = dataFromGraph.left().value();
 
-		Map<String, T> mapFromGraph = (Map<String, T>) dataV.getJson();
-		Map<String, T> valuesFrmPrev = null;
-		if (isSimpleHierarchy(label)) {
-			if (mergeValues) {
-				valuesFrmPrev = mapFromGraph.entrySet().stream().filter(e -> e.getValue().getOwnerId() != null).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
-			}
-			mapFromGraph.entrySet().removeIf(e -> preDerivedChainIdList.contains(e.getValue().getOwnerId()));
-		} else {
-			final Map<String, T> valuesFrmPrevFinal = new HashMap<>();
-			mapFromGraph.entrySet().stream().forEach(e -> {
-				T value = e.getValue();
-				value = ToscaDataDefinition.removeAndCollectByOwnerId(value, preDerivedChainIdList);
-				valuesFrmPrevFinal.put(e.getKey(), value);
-			});
-			valuesFrmPrev = valuesFrmPrevFinal;
-			mapFromGraph.entrySet().removeIf(e->e.getValue().isEmpty());
-		}
+        Map<String, T> mapFromGraph = (Map<String, T>) dataV.getJson();
+        Map<String, T> valuesFrmPrev = null;
+        if (isSimpleHierarchy(label)) {
+            if (mergeValues) {
+                valuesFrmPrev = mapFromGraph.entrySet().stream().filter(e -> e.getValue().getOwnerId() != null).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+            }
+            mapFromGraph.entrySet().removeIf(e -> preDerivedChainIdList.contains(e.getValue().getOwnerId()));
+        } else {
+            final Map<String, T> valuesFrmPrevFinal = new HashMap<>();
+            mapFromGraph.entrySet().stream().forEach(e -> {
+                T value = e.getValue();
+                value = ToscaDataDefinition.removeAndCollectByOwnerId(value, preDerivedChainIdList);
+                valuesFrmPrevFinal.put(e.getKey(), value);
+            });
+            valuesFrmPrev = valuesFrmPrevFinal;
+            mapFromGraph.entrySet().removeIf(e->e.getValue().isEmpty());
+        }
 
-		Either<Map<String, T>, StorageOperationStatus> dataFromDerived = getDataFromDerived(newDerivedList, label);
-		if (dataFromDerived.isRight()) {
-			return dataFromDerived.right().value();
-		}
-		Map<String, T> dataFromDerivedAll = dataFromDerived.left().value();
+        Either<Map<String, T>, StorageOperationStatus> dataFromDerived = getDataFromDerived(newDerivedList, label);
+        if (dataFromDerived.isRight()) {
+            return dataFromDerived.right().value();
+        }
+        Map<String, T> dataFromDerivedAll = dataFromDerived.left().value();
 
-		Either<Map<String, T>, String> merged = ToscaDataDefinition.mergeDataMaps(dataFromDerivedAll, mapFromGraph);
-		if (merged.isRight()) {
-			log.debug("property {} cannot be overriden", merged.right().value());
-			return StorageOperationStatus.INVALID_PROPERTY;
-		}
-		if (mergeValues && valuesFrmPrev != null) {
-			valuesFrmPrev.entrySet().forEach(e -> {
-				T newData = merged.left().value().get(e.getKey());
-				if (newData != null) {
-					if (isSimpleHierarchy(label)) {
-						e.getValue().mergeFunction(newData, true);
-					}else{
-						e.getValue().updateIfExist(newData, true);
-					}
-				}
-			});
-		}
-		dataV.setJson(dataFromDerivedAll);
-		Either<GraphVertex, TitanOperationStatus> updateDataV = updateOrCopyOnUpdate(dataV, nodeTypeV, label);
-		if (updateDataV.isRight()) {
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(updateDataV.right().value());
-		}
-		return StorageOperationStatus.OK;
-	}
+        Either<Map<String, T>, String> merged = ToscaDataDefinition.mergeDataMaps(dataFromDerivedAll, mapFromGraph);
+        if (merged.isRight()) {
+            log.debug("property {} cannot be overriden", merged.right().value());
+            return StorageOperationStatus.INVALID_PROPERTY;
+        }
+        if (mergeValues && valuesFrmPrev != null) {
+            valuesFrmPrev.entrySet().forEach(e -> {
+                T newData = merged.left().value().get(e.getKey());
+                if (newData != null) {
+                    if (isSimpleHierarchy(label)) {
+                        e.getValue().mergeFunction(newData, true);
+                    }else{
+                        e.getValue().updateIfExist(newData, true);
+                    }
+                }
+            });
+        }
+        dataV.setJson(dataFromDerivedAll);
+        Either<GraphVertex, TitanOperationStatus> updateDataV = updateOrCopyOnUpdate(dataV, nodeTypeV, label);
+        if (updateDataV.isRight()) {
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(updateDataV.right().value());
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private boolean isSimpleHierarchy(EdgeLabelEnum label) {
-		switch (label) {
-		case PROPERTIES:
-		case ATTRIBUTES:
-		case ADDITIONAL_INFORMATION:
-		case ARTIFACTS:
-		case GROUPS:
-		case INPUTS:
-			return true;
-		default:
-			return false;
-		}
-	}
+    private boolean isSimpleHierarchy(EdgeLabelEnum label) {
+        switch (label) {
+        case PROPERTIES:
+        case ATTRIBUTES:
+        case ADDITIONAL_INFORMATION:
+        case ARTIFACTS:
+        case GROUPS:
+        case INPUTS:
+            return true;
+        default:
+            return false;
+        }
+    }
 
-	@Override
-	public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
-		fillMetadata(elementV, (NodeType) toscaElementToUpdate);
-	}
+    @Override
+    public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
+        fillMetadata(elementV, (NodeType) toscaElementToUpdate);
+    }
 
-	public Either<ToscaElement, StorageOperationStatus> shouldUpdateDerivedVersion(ToscaElement toscaElementToUpdate, GraphVertex nodeTypeV) {
-		NodeType nodeType = (NodeType) toscaElementToUpdate;
+    public Either<ToscaElement, StorageOperationStatus> shouldUpdateDerivedVersion(ToscaElement toscaElementToUpdate, GraphVertex nodeTypeV) {
+        NodeType nodeType = (NodeType) toscaElementToUpdate;
 
-		Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
-		if (childVertex.isRight()) {
-			TitanOperationStatus getchildError = childVertex.right().value();
-			if (getchildError == TitanOperationStatus.NOT_FOUND) {
-				log.debug("derived resource for element {} not found", nodeTypeV.getUniqueId());
-				return Either.right(StorageOperationStatus.OK);
-			}
+        Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
+        if (childVertex.isRight()) {
+            TitanOperationStatus getchildError = childVertex.right().value();
+            if (getchildError == TitanOperationStatus.NOT_FOUND) {
+                log.debug("derived resource for element {} not found", nodeTypeV.getUniqueId());
+                return Either.right(StorageOperationStatus.OK);
+            }
 
-			log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchildError);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getchildError));
-		}
-		GraphVertex firstDerivedInChain = childVertex.left().value();
+            log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchildError);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getchildError));
+        }
+        GraphVertex firstDerivedInChain = childVertex.left().value();
 
-		String currentVersion = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.VERSION);
+        String currentVersion = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.VERSION);
 
-		Map<GraphPropertyEnum, Object> props = new HashMap<>();
-		props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, nodeType.getDerivedFrom().get(0));
-		props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
-		props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        Map<GraphPropertyEnum, Object> props = new HashMap<>();
+        props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, nodeType.getDerivedFrom().get(0));
+        props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
+        props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
 
-		Map<GraphPropertyEnum, Object> propsHasNot = new HashMap<>();
-		propsHasNot.put(GraphPropertyEnum.IS_DELETED, true);
-		Either<List<GraphVertex>, TitanOperationStatus> byCriteria = titanDao.getByCriteria(VertexTypeEnum.NODE_TYPE, props, propsHasNot, JsonParseFlagEnum.NoParse);
-		if (byCriteria.isRight()) {
-			log.debug("Failed to fetch derived by props {} error {}", props, byCriteria.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value()));
-		}
-		List<GraphVertex> lastDerived = byCriteria.left().value();
-		// now supported only one derived!!! Change in future!(Evg)
-		GraphVertex derivedFromHighest = lastDerived.get(0);
-		String highestVersion = (String) derivedFromHighest.getMetadataProperty(GraphPropertyEnum.VERSION);
-		if (!highestVersion.equals(currentVersion)) {
+        Map<GraphPropertyEnum, Object> propsHasNot = new HashMap<>();
+        propsHasNot.put(GraphPropertyEnum.IS_DELETED, true);
+        Either<List<GraphVertex>, TitanOperationStatus> byCriteria = titanDao.getByCriteria(VertexTypeEnum.NODE_TYPE, props, propsHasNot, JsonParseFlagEnum.NoParse);
+        if (byCriteria.isRight()) {
+            log.debug("Failed to fetch derived by props {} error {}", props, byCriteria.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value()));
+        }
+        List<GraphVertex> lastDerived = byCriteria.left().value();
+        // now supported only one derived!!! Change in future!(Evg)
+        GraphVertex derivedFromHighest = lastDerived.get(0);
+        String highestVersion = (String) derivedFromHighest.getMetadataProperty(GraphPropertyEnum.VERSION);
+        if (!highestVersion.equals(currentVersion)) {
 
-			// need to update to latest version of derived from
-			StorageOperationStatus updateDerived = updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, derivedFromHighest, true);
+            // need to update to latest version of derived from
+            StorageOperationStatus updateDerived = updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, derivedFromHighest, true);
 
-			if (updateDerived != StorageOperationStatus.OK) {
-				log.debug("Failed to update {} to highest derived {} from error {}", nodeTypeV.getUniqueId(), derivedFromHighest.getUniqueId(), updateDerived);
-				return Either.right(updateDerived);
-			}
-			return getToscaElement(nodeTypeV.getUniqueId(), new ComponentParametersView());
-		}
-		// no version changes
-		return Either.right(StorageOperationStatus.OK);
-	}
+            if (updateDerived != StorageOperationStatus.OK) {
+                log.debug("Failed to update {} to highest derived {} from error {}", nodeTypeV.getUniqueId(), derivedFromHighest.getUniqueId(), updateDerived);
+                return Either.right(updateDerived);
+            }
+            return getToscaElement(nodeTypeV.getUniqueId(), new ComponentParametersView());
+        }
+        // no version changes
+        return Either.right(StorageOperationStatus.OK);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperation.java
index d775f44..efbac33 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperation.java
@@ -1,9 +1,5 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
@@ -13,13 +9,16 @@
 import org.openecomp.sdc.be.model.PolicyDefinition;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 
 @org.springframework.stereotype.Component
 public class PolicyOperation {
 
-    private static final Logger log = LoggerFactory.getLogger(PolicyOperation.class);
+    private static final Logger log = Logger.getLogger(PolicyOperation.class.getName());
     private TopologyTemplateOperation topologyTemplateOperation;
     private TitanDao titanDao;
 
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
index d109439..9fe59d9 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
@@ -20,16 +20,10 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.stream.Collectors;
-
+import com.google.gson.reflect.TypeToken;
+import fj.data.Either;
 import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
@@ -37,1283 +31,1206 @@
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
-import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListCapabiltyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.*;
+import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
+import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.ComponentParametersView;
-import org.openecomp.sdc.be.model.DistributionStatusEnum;
-import org.openecomp.sdc.be.model.PolicyDefinition;
-import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
 import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
+import org.openecomp.sdc.be.model.operations.StorageException;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
+import org.openecomp.sdc.be.model.utils.ComponentUtilities;
 import org.openecomp.sdc.common.api.Constants;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.openecomp.sdc.common.util.ValidationUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 
-import com.google.gson.reflect.TypeToken;
-
-import fj.data.Either;
+import java.lang.reflect.Type;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
 
 @org.springframework.stereotype.Component("topology-template-operation")
 public class TopologyTemplateOperation extends ToscaElementOperation {
 
-	private static Logger log = LoggerFactory.getLogger(TopologyTemplateOperation.class.getName());
+    private static final Logger log = Logger.getLogger(TopologyTemplateOperation.class);
 
-	@Override
-	public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId) {
-		return super.getToscaElement(uniqueId);
-	}
+    @Autowired
+    private ArchiveOperation archiveOperation;
 
-	public Either<TopologyTemplate, StorageOperationStatus> createTopologyTemplate(TopologyTemplate topologyTemplate) {
-		Either<TopologyTemplate, StorageOperationStatus> result = null;
+    public Either<TopologyTemplate, StorageOperationStatus> createTopologyTemplate(TopologyTemplate topologyTemplate) {
+        Either<TopologyTemplate, StorageOperationStatus> result = null;
 
-		topologyTemplate.generateUUID();
+        topologyTemplate.generateUUID();
 
-		topologyTemplate = (TopologyTemplate) getResourceMetaDataFromResource(topologyTemplate);
-		String resourceUniqueId = topologyTemplate.getUniqueId();
-		if (resourceUniqueId == null) {
-			resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
-			topologyTemplate.setUniqueId(resourceUniqueId);
-		}
+        topologyTemplate = getResourceMetaDataFromResource(topologyTemplate);
+        String resourceUniqueId = topologyTemplate.getUniqueId();
+        if (resourceUniqueId == null) {
+            resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
+            topologyTemplate.setUniqueId(resourceUniqueId);
+        }
 
-		GraphVertex topologyTemplateVertex = new GraphVertex();
-		topologyTemplateVertex = fillMetadata(topologyTemplateVertex, topologyTemplate, JsonParseFlagEnum.ParseAll);
+        GraphVertex topologyTemplateVertex = new GraphVertex();
+        topologyTemplateVertex = fillMetadata(topologyTemplateVertex, topologyTemplate, JsonParseFlagEnum.ParseAll);
 
-		Either<GraphVertex, TitanOperationStatus> createdVertex = titanDao.createVertex(topologyTemplateVertex);
-		if (createdVertex.isRight()) {
-			TitanOperationStatus status = createdVertex.right().value();
-			log.error("Error returned after creating topology template data node {}. status returned is ", topologyTemplateVertex, status);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			return result;
-		}
+        Either<GraphVertex, TitanOperationStatus> createdVertex = titanDao.createVertex(topologyTemplateVertex);
+        if (createdVertex.isRight()) {
+            TitanOperationStatus status = createdVertex.right().value();
+            log.debug( "Error returned after creating topology template data node {}. status returned is ", topologyTemplateVertex, status);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            return result;
+        }
 
-		topologyTemplateVertex = createdVertex.left().value();
+        topologyTemplateVertex = createdVertex.left().value();
 
-		StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(topologyTemplateVertex, topologyTemplate, null);
-		if (assosiateCommon != StorageOperationStatus.OK) {
-			result = Either.right(assosiateCommon);
-			return result;
-		}
+        StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(topologyTemplateVertex, topologyTemplate, null);
+        if (assosiateCommon != StorageOperationStatus.OK) {
+            result = Either.right(assosiateCommon);
+            return result;
+        }
 
-		StorageOperationStatus associateCategory = assosiateMetadataToCategory(topologyTemplateVertex, topologyTemplate);
-		if (associateCategory != StorageOperationStatus.OK) {
-			result = Either.right(associateCategory);
-			return result;
-		}
+        StorageOperationStatus associateCategory = assosiateMetadataToCategory(topologyTemplateVertex, topologyTemplate);
+        if (associateCategory != StorageOperationStatus.OK) {
+            result = Either.right(associateCategory);
+            return result;
+        }
 
-		StorageOperationStatus associateInputs = associateInputsToComponent(topologyTemplateVertex, topologyTemplate);
-		if (associateInputs != StorageOperationStatus.OK) {
-			result = Either.right(associateInputs);
-			return result;
-		}
-		StorageOperationStatus associateGroups = associateGroupsToComponent(topologyTemplateVertex, topologyTemplate);
-		if (associateGroups != StorageOperationStatus.OK) {
-			result = Either.right(associateGroups);
-			return result;
-		}
-		StorageOperationStatus associatePolicies = associatePoliciesToComponent(topologyTemplateVertex, topologyTemplate);
-		if (associatePolicies != StorageOperationStatus.OK) {
-			result = Either.right(associatePolicies);
-			return result;
-		}
-		StorageOperationStatus associateInstAttr = associateInstAttributesToComponent(topologyTemplateVertex, topologyTemplate);
-		if (associateInstAttr != StorageOperationStatus.OK) {
-			result = Either.right(associateInstAttr);
-			return result;
-		}
-		StorageOperationStatus associateInstProperties = associateInstPropertiesToComponent(topologyTemplateVertex, topologyTemplate);
-		if (associateInstProperties != StorageOperationStatus.OK) {
-			result = Either.right(associateInstProperties);
-			return result;
-		}
-		StorageOperationStatus associateInstInputs = associateInstInputsToComponent(topologyTemplateVertex, topologyTemplate);
-		if (associateInstProperties != StorageOperationStatus.OK) {
-			result = Either.right(associateInstInputs);
-			return result;
-		}
-		StorageOperationStatus associateInstGroups = associateInstGroupsToComponent(topologyTemplateVertex, topologyTemplate);
-		if (associateInstGroups != StorageOperationStatus.OK) {
-			result = Either.right(associateInstInputs);
-			return result;
-		}
-		
-		StorageOperationStatus associateRequirements = associateRequirementsToResource(topologyTemplateVertex, topologyTemplate);
-		if (associateRequirements != StorageOperationStatus.OK) {
-			result = Either.right(associateRequirements);
-			return result;
-		}
+        StorageOperationStatus associateInputs = associateInputsToComponent(topologyTemplateVertex, topologyTemplate);
+        if (associateInputs != StorageOperationStatus.OK) {
+            result = Either.right(associateInputs);
+            return result;
+        }
+        StorageOperationStatus associateGroups = associateGroupsToComponent(topologyTemplateVertex, topologyTemplate);
+        if (associateGroups != StorageOperationStatus.OK) {
+            result = Either.right(associateGroups);
+            return result;
+        }
+        StorageOperationStatus associatePolicies = associatePoliciesToComponent(topologyTemplateVertex, topologyTemplate);
+        if (associatePolicies != StorageOperationStatus.OK) {
+            result = Either.right(associatePolicies);
+            return result;
+        }
+        StorageOperationStatus associateInstAttr = associateInstAttributesToComponent(topologyTemplateVertex, topologyTemplate);
+        if (associateInstAttr != StorageOperationStatus.OK) {
+            result = Either.right(associateInstAttr);
+            return result;
+        }
+        StorageOperationStatus associateInstProperties = associateInstPropertiesToComponent(topologyTemplateVertex, topologyTemplate);
+        if (associateInstProperties != StorageOperationStatus.OK) {
+            result = Either.right(associateInstProperties);
+            return result;
+        }
+        StorageOperationStatus associateInstInputs = associateInstInputsToComponent(topologyTemplateVertex, topologyTemplate);
+        if (associateInstProperties != StorageOperationStatus.OK) {
+            result = Either.right(associateInstInputs);
+            return result;
+        }
+        StorageOperationStatus associateInstGroups = associateInstGroupsToComponent(topologyTemplateVertex, topologyTemplate);
+        if (associateInstGroups != StorageOperationStatus.OK) {
+            result = Either.right(associateInstInputs);
+            return result;
+        }
 
-		StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(topologyTemplateVertex, topologyTemplate);
-		if (associateCapabilities != StorageOperationStatus.OK) {
-			result = Either.right(associateCapabilities);
-			return result;
-		}
+        StorageOperationStatus associateRequirements = associateRequirementsToResource(topologyTemplateVertex, topologyTemplate);
+        if (associateRequirements != StorageOperationStatus.OK) {
+            result = Either.right(associateRequirements);
+            return result;
+        }
 
-		StorageOperationStatus associateArtifacts = associateTopologyTemplateArtifactsToComponent(topologyTemplateVertex, topologyTemplate);
-		if (associateArtifacts != StorageOperationStatus.OK) {
-			result = Either.right(associateArtifacts);
-			return result;
-		}
+        StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(topologyTemplateVertex, topologyTemplate);
+        if (associateCapabilities != StorageOperationStatus.OK) {
+            result = Either.right(associateCapabilities);
+            return result;
+        }
 
-		StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(topologyTemplateVertex, topologyTemplate);
-		if (addAdditionalInformation != StorageOperationStatus.OK) {
-			result = Either.right(addAdditionalInformation);
-			return result;
-		}
-		StorageOperationStatus associateCapProperties = associateCapPropertiesToResource(topologyTemplateVertex, topologyTemplate);
-		if (associateCapProperties != StorageOperationStatus.OK) {
-			result = Either.right(associateCapProperties);
-			return result;
-		}
+        StorageOperationStatus associateArtifacts = associateTopologyTemplateArtifactsToComponent(topologyTemplateVertex, topologyTemplate);
+        if (associateArtifacts != StorageOperationStatus.OK) {
+            result = Either.right(associateArtifacts);
+            return result;
+        }
 
-		StorageOperationStatus associateInterfaces = associateInterfacesToResource(topologyTemplateVertex, topologyTemplate);
-		if (associateInterfaces != StorageOperationStatus.OK) {
-			result = Either.right(associateInterfaces);
-			return result;
-		}
+        StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(topologyTemplateVertex, topologyTemplate);
+        if (addAdditionalInformation != StorageOperationStatus.OK) {
+            result = Either.right(addAdditionalInformation);
+            return result;
+        }
+        StorageOperationStatus associateCapProperties = associateCapPropertiesToResource(topologyTemplateVertex, topologyTemplate);
+        if (associateCapProperties != StorageOperationStatus.OK) {
+            result = Either.right(associateCapProperties);
+            return result;
+        }
+        StorageOperationStatus associatePathProperties = associateForwardingPathToResource(topologyTemplateVertex, topologyTemplate);
+        if (associateCapProperties != StorageOperationStatus.OK) {
+            result = Either.right(associatePathProperties);
+            return result;
+        }
 
-		StorageOperationStatus associatePathProperties = associateForwardingPathToResource(topologyTemplateVertex, topologyTemplate);
-		if (associateCapProperties != StorageOperationStatus.OK) {
-			result = Either.right(associatePathProperties);
-			return result;
-		}
 
+        return Either.left(topologyTemplate);
 
-		return Either.left(topologyTemplate);
+    }
 
-	}
+    private StorageOperationStatus associatePoliciesToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        return associatePoliciesToComponent(nodeTypeVertex, topologyTemplate.getPolicies());
+    }
 
-	private StorageOperationStatus associatePoliciesToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		return associatePoliciesToComponent(nodeTypeVertex, topologyTemplate.getPolicies());
-	}
+    private StorageOperationStatus associatePoliciesToComponent(GraphVertex nodeTypeVertex,    Map<String, PolicyDataDefinition> policies) {
+        if (policies != null && !policies.isEmpty()) {
+            policies.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
+                String uid = UniqueIdBuilder.buildGroupingUid(nodeTypeVertex.getUniqueId(), p.getName());
+                p.setUniqueId(uid);
+            });
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.POLICIES, EdgeLabelEnum.POLICIES, policies);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private StorageOperationStatus associatePoliciesToComponent(GraphVertex nodeTypeVertex,	Map<String, PolicyDataDefinition> policies) {
-		if (policies != null && !policies.isEmpty()) {
-			policies.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
-				String uid = UniqueIdBuilder.buildGroupingUid(nodeTypeVertex.getUniqueId(), p.getName());
-				p.setUniqueId(uid);
-			});
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.POLICIES, EdgeLabelEnum.POLICIES, policies);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    private StorageOperationStatus associateForwardingPathToResource(GraphVertex topologyTemplateVertex, TopologyTemplate topologyTemplate) {
+        Map<String, ForwardingPathDataDefinition> forwardingPaths = topologyTemplate.getForwardingPaths();
+        return associateForwardingPathToComponent(topologyTemplateVertex,forwardingPaths);
+    }
 
-	private StorageOperationStatus associateForwardingPathToResource(GraphVertex topologyTemplateVertex, TopologyTemplate topologyTemplate) {
-		Map<String, ForwardingPathDataDefinition> forwardingPaths = topologyTemplate.getForwardingPaths();
-		return associateForwardingPathToComponent(topologyTemplateVertex,forwardingPaths);
-	}
+    private StorageOperationStatus associateCapPropertiesToResource(GraphVertex topologyTemplateVertex, TopologyTemplate topologyTemplate) {
+        Map<String, MapCapabilityProperty> calculatedCapProperties = topologyTemplate.getCalculatedCapabilitiesProperties();
+        if (calculatedCapProperties != null && !calculatedCapProperties.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(topologyTemplateVertex, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, calculatedCapProperties);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private StorageOperationStatus associateCapPropertiesToResource(GraphVertex topologyTemplateVertex, TopologyTemplate topologyTemplate) {
-		Map<String, MapCapabiltyProperty> calculatedCapProperties = topologyTemplate.getCalculatedCapabilitiesProperties();
-		if (calculatedCapProperties != null && !calculatedCapProperties.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(topologyTemplateVertex, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, calculatedCapProperties);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        Map<String, MapListCapabilityDataDefinition> calculatedCapabilities = topologyTemplate.getCalculatedCapabilities();
+        if (calculatedCapabilities != null && !calculatedCapabilities.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CALCULATED_CAPABILITIES, EdgeLabelEnum.CALCULATED_CAPABILITIES, calculatedCapabilities);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        Map<String, MapListCapabilityDataDefinition> fullfilledCapabilities = topologyTemplate.getFullfilledCapabilities();
+        if (fullfilledCapabilities != null && !fullfilledCapabilities.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.FULLFILLED_CAPABILITIES, EdgeLabelEnum.FULLFILLED_CAPABILITIES, fullfilledCapabilities);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
 
-	private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		Map<String, MapListCapabiltyDataDefinition> calculatedCapabilities = topologyTemplate.getCalculatedCapabilities();
-		if (calculatedCapabilities != null && !calculatedCapabilities.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CALCULATED_CAPABILITIES, EdgeLabelEnum.CALCULATED_CAPABILITIES, calculatedCapabilities);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilities = topologyTemplate.getFullfilledCapabilities();
-		if (fullfilledCapabilities != null && !fullfilledCapabilities.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.FULLFILLED_CAPABILITIES, EdgeLabelEnum.FULLFILLED_CAPABILITIES, fullfilledCapabilities);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
+    }
 
-	}
+    private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        Map<String, MapListRequirementDataDefinition> calculatedRequirements = topologyTemplate.getCalculatedRequirements();
+        if (calculatedRequirements != null && !calculatedRequirements.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CALCULATED_REQUIREMENTS, EdgeLabelEnum.CALCULATED_REQUIREMENTS, calculatedRequirements);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        Map<String, MapListRequirementDataDefinition> fullfilledRequirements = topologyTemplate.getFullfilledRequirements();
+        if (fullfilledRequirements != null && !fullfilledRequirements.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.FULLFILLED_REQUIREMENTS, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, fullfilledRequirements);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		Map<String, MapListRequirementDataDefinition> calculatedRequirements = topologyTemplate.getCalculatedRequirements();
-		if (calculatedRequirements != null && !calculatedRequirements.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CALCULATED_REQUIREMENTS, EdgeLabelEnum.CALCULATED_REQUIREMENTS, calculatedRequirements);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		Map<String, MapListRequirementDataDefinition> fullfilledRequirements = topologyTemplate.getFullfilledRequirements();
-		if (fullfilledRequirements != null && !fullfilledRequirements.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.FULLFILLED_REQUIREMENTS, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, fullfilledRequirements);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    private StorageOperationStatus associateTopologyTemplateArtifactsToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        Map<String, ArtifactDataDefinition> addInformation = topologyTemplate.getServiceApiArtifacts();
 
-	private StorageOperationStatus associateTopologyTemplateArtifactsToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		Map<String, ArtifactDataDefinition> addInformation = topologyTemplate.getServiceApiArtifacts();
+        if (addInformation != null && !addInformation.isEmpty()) {
+            addInformation.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
+                String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
+                a.setUniqueId(uniqueId);
+            });
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.SERVICE_API_ARTIFACTS, EdgeLabelEnum.SERVICE_API_ARTIFACTS, addInformation);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        Map<String, MapArtifactDataDefinition> instArtifacts = topologyTemplate.getInstDeploymentArtifacts();
 
-		if (addInformation != null && !addInformation.isEmpty()) {
-			addInformation.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
-				String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
-				a.setUniqueId(uniqueId);
-			});
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.SERVICE_API_ARTIFACTS, EdgeLabelEnum.SERVICE_API_ARTIFACTS, addInformation);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		Map<String, MapArtifactDataDefinition> instArtifacts = topologyTemplate.getInstDeploymentArtifacts();
+        if (instArtifacts != null && !instArtifacts.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, instArtifacts);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        Map<String, MapArtifactDataDefinition> instInfoArtifacts = topologyTemplate.getInstanceArtifacts();
 
-		if (instArtifacts != null && !instArtifacts.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, instArtifacts);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		Map<String, MapArtifactDataDefinition> instInfoArtifacts = topologyTemplate.getInstanceArtifacts();
+        if (instInfoArtifacts != null && !instInfoArtifacts.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INSTANCE_ARTIFACTS, EdgeLabelEnum.INSTANCE_ARTIFACTS, instInfoArtifacts);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		if (instInfoArtifacts != null && !instInfoArtifacts.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INSTANCE_ARTIFACTS, EdgeLabelEnum.INSTANCE_ARTIFACTS, instInfoArtifacts);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
 
-	private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        Map<String, AdditionalInfoParameterDataDefinition> addInformation = topologyTemplate.getAdditionalInformation();
 
-		Map<String, AdditionalInfoParameterDataDefinition> addInformation = topologyTemplate.getAdditionalInformation();
+        if (addInformation != null && !addInformation.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformation);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		if (addInformation != null && !addInformation.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformation);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    public StorageOperationStatus associateInstPropertiesToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        Map<String, MapPropertiesDataDefinition> instProps = topologyTemplate.getInstProperties();
+        return associateInstPropertiesToComponent(nodeTypeVertex, instProps);
+    }
 
-	public StorageOperationStatus associateInstPropertiesToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		Map<String, MapPropertiesDataDefinition> instProps = topologyTemplate.getInstProperties();
-		return associateInstPropertiesToComponent(nodeTypeVertex, instProps);
-	}
+    public StorageOperationStatus associateInstInputsToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        Map<String, MapPropertiesDataDefinition> instProps = topologyTemplate.getInstInputs();
+        return associateInstInputsToComponent(nodeTypeVertex, instProps);
+    }
 
-	public StorageOperationStatus associateInstInputsToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		Map<String, MapPropertiesDataDefinition> instProps = topologyTemplate.getInstInputs();
-		return associateInstInputsToComponent(nodeTypeVertex, instProps);
-	}
-	
-	public StorageOperationStatus associateInstGroupsToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		Map<String, MapGroupsDataDefinition> instGroups = topologyTemplate.getInstGroups();
-		return associateInstGroupsToComponent(nodeTypeVertex, instGroups);
-	}
-	
+    public StorageOperationStatus associateInstGroupsToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        Map<String, MapGroupsDataDefinition> instGroups = topologyTemplate.getInstGroups();
+        return associateInstGroupsToComponent(nodeTypeVertex, instGroups);
+    }
 
-	public StorageOperationStatus associateInstPropertiesToComponent(GraphVertex nodeTypeVertex, Map<String, MapPropertiesDataDefinition> instProps) {
-		if (instProps != null && !instProps.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INST_PROPERTIES, EdgeLabelEnum.INST_PROPERTIES, instProps);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
 
-	public StorageOperationStatus associateInstInputsToComponent(GraphVertex nodeTypeVertex, Map<String, MapPropertiesDataDefinition> instInputs) {
-		if (instInputs != null && !instInputs.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, instInputs);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
-	
-	public StorageOperationStatus associateInstGroupsToComponent(GraphVertex nodeTypeVertex, Map<String, MapGroupsDataDefinition> instGroups) {
-		if (instGroups != null && !instGroups.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, instGroups);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    public StorageOperationStatus associateInstPropertiesToComponent(GraphVertex nodeTypeVertex, Map<String, MapPropertiesDataDefinition> instProps) {
+        if (instProps != null && !instProps.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INST_PROPERTIES, EdgeLabelEnum.INST_PROPERTIES, instProps);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
+    public StorageOperationStatus associateInstInputsToComponent(GraphVertex nodeTypeVertex, Map<String, MapPropertiesDataDefinition> instInputs) {
+        if (instInputs != null && !instInputs.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, instInputs);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	public StorageOperationStatus deleteInstInputsToComponent(GraphVertex nodeTypeVertex, Map<String, MapPropertiesDataDefinition> instInputs) {
+    public StorageOperationStatus associateInstGroupsToComponent(GraphVertex nodeTypeVertex, Map<String, MapGroupsDataDefinition> instGroups) {
+        if (instGroups != null && !instGroups.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, instGroups);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		if (instInputs != null && !instInputs.isEmpty()) {
-			instInputs.entrySet().forEach(i -> {
-				List<String> uniqueKeys = new ArrayList<String>(i.getValue().getMapToscaDataDefinition().keySet());
-				List<String> pathKeys = new ArrayList<String>();
-				pathKeys.add(i.getKey());
 
-				StorageOperationStatus status = deleteToscaDataDeepElements(nodeTypeVertex, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, uniqueKeys, pathKeys, JsonPresentationFields.NAME);
-				if (status != StorageOperationStatus.OK) {
-					return;
-				}
-			});
-		}
+    public StorageOperationStatus deleteInstInputsToComponent(GraphVertex nodeTypeVertex, Map<String, MapPropertiesDataDefinition> instInputs) {
 
-		return StorageOperationStatus.OK;
-	}
+        if (instInputs != null && !instInputs.isEmpty()) {
+            instInputs.entrySet().forEach(i -> {
+                List<String> uniqueKeys = new ArrayList<>(i.getValue().getMapToscaDataDefinition().keySet());
+                List<String> pathKeys = new ArrayList<>();
+                pathKeys.add(i.getKey());
 
-	public StorageOperationStatus addInstPropertiesToComponent(GraphVertex nodeTypeVertex, Map<String, MapPropertiesDataDefinition> instInputs) {
+                StorageOperationStatus status = deleteToscaDataDeepElements(nodeTypeVertex, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, uniqueKeys, pathKeys, JsonPresentationFields.NAME);
+                if (status != StorageOperationStatus.OK) {
+                    return;
+                }
+            });
+        }
 
-		if (instInputs != null && !instInputs.isEmpty()) {
-			instInputs.entrySet().forEach(i -> {
-				StorageOperationStatus status = addToscaDataDeepElementsBlockToToscaElement(nodeTypeVertex, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, i.getValue(), i.getKey());
-				if (status != StorageOperationStatus.OK) {
-					return;
-				}
-			});
-		}
+        return StorageOperationStatus.OK;
+    }
 
-		return StorageOperationStatus.OK;
-	}
+    public StorageOperationStatus addInstPropertiesToComponent(GraphVertex nodeTypeVertex, Map<String, MapPropertiesDataDefinition> instInputs) {
 
-	public StorageOperationStatus associateInstDeploymentArtifactsToComponent(GraphVertex nodeTypeVertex, Map<String, MapArtifactDataDefinition> instArtifacts) {
-		return associateInstanceArtifactsToComponent(nodeTypeVertex, instArtifacts, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
-	}
-	
-	public StorageOperationStatus associateInstArtifactsToComponent(GraphVertex nodeTypeVertex, Map<String, MapArtifactDataDefinition> instArtifacts) {
-		return associateInstanceArtifactsToComponent(nodeTypeVertex, instArtifacts, VertexTypeEnum.INSTANCE_ARTIFACTS, EdgeLabelEnum.INSTANCE_ARTIFACTS);
-	}
+        if (instInputs != null && !instInputs.isEmpty()) {
+            instInputs.entrySet().forEach(i -> {
+                StorageOperationStatus status = addToscaDataDeepElementsBlockToToscaElement(nodeTypeVertex, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, i.getValue(), i.getKey());
+                if (status != StorageOperationStatus.OK) {
+                    return;
+                }
+            });
+        }
 
-	private StorageOperationStatus associateInstanceArtifactsToComponent(GraphVertex nodeTypeVertex, Map<String, MapArtifactDataDefinition> instProps, VertexTypeEnum vertexType, EdgeLabelEnum edgeLabel) {
-		if (instProps != null && !instProps.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, vertexType, edgeLabel, instProps);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+        return StorageOperationStatus.OK;
+    }
 
-	public StorageOperationStatus associateCalcCapReqToComponent(GraphVertex nodeTypeVertex, Map<String, MapListRequirementDataDefinition> calcRequirements, Map<String, MapListCapabiltyDataDefinition> calcCapabilty, Map<String, MapCapabiltyProperty> calculatedCapabilitiesProperties) {
-		if (calcRequirements != null && !calcRequirements.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CALCULATED_REQUIREMENTS, EdgeLabelEnum.CALCULATED_REQUIREMENTS, calcRequirements);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-			Map<String, MapListRequirementDataDefinition> fullFilled = new HashMap<>();
-			assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.FULLFILLED_REQUIREMENTS, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, fullFilled);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		if (calcCapabilty != null && !calcCapabilty.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CALCULATED_CAPABILITIES, EdgeLabelEnum.CALCULATED_CAPABILITIES, calcCapabilty);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-			Map<String, MapListCapabiltyDataDefinition> fullFilled = new HashMap<>();
-			assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.FULLFILLED_CAPABILITIES, EdgeLabelEnum.FULLFILLED_CAPABILITIES, fullFilled);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		if ( calculatedCapabilitiesProperties != null && !calculatedCapabilitiesProperties.isEmpty() ){
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, calculatedCapabilitiesProperties);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    public StorageOperationStatus associateInstDeploymentArtifactsToComponent(GraphVertex nodeTypeVertex, Map<String, MapArtifactDataDefinition> instArtifacts) {
+        return associateInstanceArtifactsToComponent(nodeTypeVertex, instArtifacts, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
+    }
 
-	private StorageOperationStatus associateInstAttributesToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		Map<String, MapPropertiesDataDefinition> instAttr = topologyTemplate.getInstAttributes();
-		return associateInstAttributeToComponent(nodeTypeVertex, instAttr);
-	}
+    public StorageOperationStatus associateInstArtifactsToComponent(GraphVertex nodeTypeVertex, Map<String, MapArtifactDataDefinition> instArtifacts) {
+        return associateInstanceArtifactsToComponent(nodeTypeVertex, instArtifacts, VertexTypeEnum.INSTANCE_ARTIFACTS, EdgeLabelEnum.INSTANCE_ARTIFACTS);
+    }
 
-	public StorageOperationStatus associateForwardingPathToComponent(GraphVertex nodeTypeVertex, Map<String, ForwardingPathDataDefinition> forwardingPathMap) {
-		if (forwardingPathMap != null && !forwardingPathMap.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.FORWARDING_PATH, EdgeLabelEnum.FORWARDING_PATH, forwardingPathMap);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    private StorageOperationStatus associateInstanceArtifactsToComponent(GraphVertex nodeTypeVertex, Map<String, MapArtifactDataDefinition> instProps, VertexTypeEnum vertexType, EdgeLabelEnum edgeLabel) {
+        if (instProps != null && !instProps.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, vertexType, edgeLabel, instProps);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	public StorageOperationStatus associateInstAttributeToComponent(GraphVertex nodeTypeVertex, Map<String, MapPropertiesDataDefinition> instAttr) {
-		if (instAttr != null && !instAttr.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INST_ATTRIBUTES, EdgeLabelEnum.INST_ATTRIBUTES, instAttr);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    public StorageOperationStatus associateOrAddCalcCapReqToComponent(GraphVertex nodeTypeVertex, Map<String, MapListRequirementDataDefinition> calcRequirements, Map<String, MapListCapabilityDataDefinition> calcCapabilty, Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties) {
+        if (calcRequirements != null && !calcRequirements.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateOrAddElementToData(nodeTypeVertex, VertexTypeEnum.CALCULATED_REQUIREMENTS, EdgeLabelEnum.CALCULATED_REQUIREMENTS, calcRequirements);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+            Map<String, MapListRequirementDataDefinition> fullFilled = new HashMap<>();
+            assosiateElementToData = associateOrAddElementToData(nodeTypeVertex, VertexTypeEnum.FULLFILLED_REQUIREMENTS, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, fullFilled);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        if (calcCapabilty != null && !calcCapabilty.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateOrAddElementToData(nodeTypeVertex, VertexTypeEnum.CALCULATED_CAPABILITIES ,EdgeLabelEnum.CALCULATED_CAPABILITIES, calcCapabilty);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+            Map<String, MapListCapabilityDataDefinition> fullFilled = new HashMap<>();
+            assosiateElementToData = associateOrAddElementToData(nodeTypeVertex, VertexTypeEnum.FULLFILLED_CAPABILITIES, EdgeLabelEnum.FULLFILLED_CAPABILITIES, fullFilled);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        if ( calculatedCapabilitiesProperties != null && !calculatedCapabilitiesProperties.isEmpty() ){
+            return associateOrAddElementToData(nodeTypeVertex, VertexTypeEnum.CALCULATED_CAP_PROPERTIES,
+                    EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, calculatedCapabilitiesProperties)
+                    .right()
+                    .on(v -> StorageOperationStatus.OK);
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	public StorageOperationStatus associateGroupsToComponent(GraphVertex nodeTypeVertex, Map<String, GroupDataDefinition> groups) {
+    private <T extends MapDataDefinition> Either<GraphVertex, StorageOperationStatus> associateOrAddElementToData(GraphVertex nodeTypeVertex, VertexTypeEnum vertexTypeEnum, EdgeLabelEnum edgeLabelEnum, Map<String, T> dataMap){
+        return titanDao.getChildVertex(nodeTypeVertex, edgeLabelEnum, JsonParseFlagEnum.ParseJson)
+                .either(dataVertex -> addElementsToComponent(nodeTypeVertex, dataVertex, vertexTypeEnum, edgeLabelEnum, dataMap),
+                        status -> associateElementToDataIfNotFound(status, nodeTypeVertex, vertexTypeEnum, edgeLabelEnum, dataMap));
+    }
+    
+    private Either<GraphVertex, StorageOperationStatus> associateElementToDataIfNotFound(TitanOperationStatus status, GraphVertex nodeTypeVertex, VertexTypeEnum vertexTypeEnum, EdgeLabelEnum edgeLabelEnum, Map<String, ? extends ToscaDataDefinition> dataMap) {
+        if(status == TitanOperationStatus.NOT_FOUND){
+            return associateElementToData(nodeTypeVertex, vertexTypeEnum, edgeLabelEnum, dataMap);
+        }
+        return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+    }
 
-		if (groups != null && !groups.isEmpty()) {
-			groups.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
-				String uid = UniqueIdBuilder.buildGroupingUid(nodeTypeVertex.getUniqueId(), p.getName());
-				p.setUniqueId(uid);
-			});
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.GROUPS, EdgeLabelEnum.GROUPS, groups);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    private <T extends MapDataDefinition> Either<GraphVertex, StorageOperationStatus> addElementsToComponent(GraphVertex nodeTypeVertex, GraphVertex dataVertex, VertexTypeEnum vertexTypeEnum, EdgeLabelEnum edgeLabelEnum, Map<String, T> dataMap) {
+        Optional<StorageOperationStatus> error = dataMap.entrySet()
+                .stream()
+                .map(e -> addElementToComponent(nodeTypeVertex.getUniqueId(), vertexTypeEnum, edgeLabelEnum, e))
+                .filter(s -> s != StorageOperationStatus.OK)
+                .findFirst();
+        if(error.isPresent()){
+            return Either.right(error.get());
+        }
+        return Either.left(dataVertex);
+    }
 
-	private StorageOperationStatus associateGroupsToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		return associateGroupsToComponent(nodeTypeVertex, topologyTemplate.getGroups());
-	}
+    private StorageOperationStatus associateInstAttributesToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        Map<String, MapPropertiesDataDefinition> instAttr = topologyTemplate.getInstAttributes();
+        return associateInstAttributeToComponent(nodeTypeVertex, instAttr);
+    }
 
-	public StorageOperationStatus associateInputsToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		Map<String, PropertyDataDefinition> inputs = topologyTemplate.getInputs();
-		return associateInputsToComponent(nodeTypeVertex, inputs, topologyTemplate.getUniqueId());
-	}
+    public StorageOperationStatus associateForwardingPathToComponent(GraphVertex nodeTypeVertex, Map<String, ForwardingPathDataDefinition> forwardingPathMap) {
+        if (forwardingPathMap != null && !forwardingPathMap.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.FORWARDING_PATH, EdgeLabelEnum.FORWARDING_PATH, forwardingPathMap);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	public StorageOperationStatus associateInputsToComponent(GraphVertex nodeTypeVertex, Map<String, PropertyDataDefinition> inputs, String id) {
-		if (inputs != null && !inputs.isEmpty()) {
-			inputs.values().stream().filter(e -> e.getUniqueId() == null).forEach(e -> e.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(id, e.getName())));
+    public StorageOperationStatus associateInstAttributeToComponent(GraphVertex nodeTypeVertex, Map<String, MapPropertiesDataDefinition> instAttr) {
+        if (instAttr != null && !instAttr.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INST_ATTRIBUTES, EdgeLabelEnum.INST_ATTRIBUTES, instAttr);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INPUTS, EdgeLabelEnum.INPUTS, inputs);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    public StorageOperationStatus associateGroupsToComponent(GraphVertex nodeTypeVertex, Map<String, GroupDataDefinition> groups) {
 
-	private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate, JsonParseFlagEnum flag) {
-		nodeTypeVertex.setLabel(VertexTypeEnum.TOPOLOGY_TEMPLATE);
-		fillCommonMetadata(nodeTypeVertex, topologyTemplate);
-		if (flag == JsonParseFlagEnum.ParseAll || flag == JsonParseFlagEnum.ParseJson) {
-			nodeTypeVertex.setJson(topologyTemplate.getCompositions());
-		}
-		nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.CSAR_UUID, topologyTemplate.getMetadataValue(JsonPresentationFields.CSAR_UUID));
-		nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, topologyTemplate.getMetadataValue(JsonPresentationFields.DISTRIBUTION_STATUS));
-		
-		return nodeTypeVertex;
+        if (groups != null && !groups.isEmpty()) {
+            groups.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
+                String uid = UniqueIdBuilder.buildGroupingUid(nodeTypeVertex.getUniqueId(), p.getName());
+                p.setUniqueId(uid);
+            });
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.GROUPS, EdgeLabelEnum.GROUPS, groups);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-	}
+    private StorageOperationStatus associateGroupsToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        return associateGroupsToComponent(nodeTypeVertex, topologyTemplate.getGroups());
+    }
 
-	private StorageOperationStatus assosiateMetadataToCategory(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		if (topologyTemplate.getResourceType() == null) {
-			// service
-			return associateServiceMetadataToCategory(nodeTypeVertex, topologyTemplate);
-		} else {
-			// VF
-			return assosiateResourceMetadataToCategory(nodeTypeVertex, topologyTemplate);
-		}
-	}
+    public StorageOperationStatus associateInputsToComponent(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        Map<String, PropertyDataDefinition> inputs = topologyTemplate.getInputs();
+        return associateInputsToComponent(nodeTypeVertex, inputs, topologyTemplate.getUniqueId());
+    }
 
-	private StorageOperationStatus associateServiceMetadataToCategory(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
-		String categoryName = topologyTemplate.getCategories().get(0).getName();
-		Either<GraphVertex, StorageOperationStatus> category = categoryOperation.getCategory(categoryName, VertexTypeEnum.SERVICE_CATEGORY);
-		if (category.isRight()) {
-			log.trace("NO category {} for service {}", categoryName, topologyTemplate.getUniqueId());
-			return StorageOperationStatus.CATEGORY_NOT_FOUND;
-		}
-		GraphVertex categoryV = category.left().value();
-		TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, categoryV, EdgeLabelEnum.CATEGORY, new HashMap<>());
-		if (createEdge != TitanOperationStatus.OK) {
-			log.trace("Failed to associate resource {} to category {} with id {}", topologyTemplate.getUniqueId(), categoryName, categoryV.getUniqueId());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
-		}
-		return StorageOperationStatus.OK;
-	}
+    public StorageOperationStatus associateInputsToComponent(GraphVertex nodeTypeVertex, Map<String, PropertyDataDefinition> inputs, String id) {
+        if (inputs != null && !inputs.isEmpty()) {
+            inputs.values().stream().filter(e -> e.getUniqueId() == null).forEach(e -> e.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(id, e.getName())));
 
-	@Override
-	public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
-		JsonParseFlagEnum parseFlag = componentParametersView.detectParseFlag();
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INPUTS, EdgeLabelEnum.INPUTS, inputs);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.TopologyTemplate, parseFlag);
-		if (componentByLabelAndId.isRight()) {
-			return Either.right(componentByLabelAndId.right().value());
-		}
-		GraphVertex componentV = componentByLabelAndId.left().value();
+    private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate, JsonParseFlagEnum flag) {
+        nodeTypeVertex.setLabel(VertexTypeEnum.TOPOLOGY_TEMPLATE);
+        fillCommonMetadata(nodeTypeVertex, topologyTemplate);
+        if (flag == JsonParseFlagEnum.ParseAll || flag == JsonParseFlagEnum.ParseJson) {
+            nodeTypeVertex.setJson(topologyTemplate.getCompositions());
+        }
+        nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.CSAR_UUID, topologyTemplate.getMetadataValue(JsonPresentationFields.CSAR_UUID));
+        nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, topologyTemplate.getMetadataValue(JsonPresentationFields.DISTRIBUTION_STATUS));
 
-		return getToscaElement(componentV, componentParametersView);
+        return nodeTypeVertex;
 
-	}
-	// -------------------------------------------------------------
+    }
 
-	public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
-		TopologyTemplate toscaElement;
+    private StorageOperationStatus assosiateMetadataToCategory(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        if (topologyTemplate.getResourceType() == null) {
+            // service
+            return associateServiceMetadataToCategory(nodeTypeVertex, topologyTemplate);
+        } else {
+            // VF
+            return assosiateResourceMetadataToCategory(nodeTypeVertex, topologyTemplate);
+        }
+    }
 
-		toscaElement = convertToTopologyTemplate(componentV);
-		TitanOperationStatus status;
-		if (!componentParametersView.isIgnoreUsers()) {
-			status = setCreatorFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
+    private StorageOperationStatus associateServiceMetadataToCategory(GraphVertex nodeTypeVertex, TopologyTemplate topologyTemplate) {
+        String categoryName = topologyTemplate.getCategories().get(0).getName();
+        Either<GraphVertex, StorageOperationStatus> category = categoryOperation.getCategory(categoryName, VertexTypeEnum.SERVICE_CATEGORY);
+        if (category.isRight()) {
+            log.trace("NO category {} for service {}", categoryName, topologyTemplate.getUniqueId());
+            return StorageOperationStatus.CATEGORY_NOT_FOUND;
+        }
+        GraphVertex categoryV = category.left().value();
+        TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, categoryV, EdgeLabelEnum.CATEGORY, new HashMap<>());
+        if (createEdge != TitanOperationStatus.OK) {
+            log.trace("Failed to associate resource {} to category {} with id {}", topologyTemplate.getUniqueId(), categoryName, categoryV.getUniqueId());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
+        }
+        return StorageOperationStatus.OK;
+    }
 
-			status = setLastModifierFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (!componentParametersView.isIgnoreCategories()) {
-			status = setTopologyTempalteCategoriesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+    @Override
+    public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
+        JsonParseFlagEnum parseFlag = componentParametersView.detectParseFlag();
 
-			}
-		}
-		if (!componentParametersView.isIgnoreArtifacts()) {
-			TitanOperationStatus storageStatus = setAllArtifactsFromGraph(componentV, toscaElement);
-			if (storageStatus != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(storageStatus));
-			}
-		}
-		if (!componentParametersView.isIgnoreComponentInstancesProperties()) {
-			status = setComponentInstancesPropertiesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (!componentParametersView.isIgnoreCapabilities()) {
-			status = setCapabilitiesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (!componentParametersView.isIgnoreRequirements()) {
-			status = setRequirementsFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (!componentParametersView.isIgnoreAllVersions()) {
-			status = setAllVersions(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (!componentParametersView.isIgnoreAdditionalInformation()) {
-			status = setAdditionalInformationFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
+        Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.TOPOLOGY_TEMPLATE, parseFlag);
+        if (componentByLabelAndId.isRight()) {
+            return Either.right(componentByLabelAndId.right().value());
+        }
+        GraphVertex componentV = componentByLabelAndId.left().value();
 
-		if (!componentParametersView.isIgnoreGroups()) {
-			status = setGroupsFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
+        return getToscaElement(componentV, componentParametersView);
 
-		}
-		if (!componentParametersView.isIgnorePolicies()) {
-			status = setPoliciesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
+    }
+    // -------------------------------------------------------------
 
-		}
-		if (!componentParametersView.isIgnoreComponentInstances()) {
-			status = setInstGroupsFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
+    public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
+        TopologyTemplate toscaElement;
 
-		}
-		if (!componentParametersView.isIgnoreInputs()) {
-			status = setInputsFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
+        toscaElement = convertToTopologyTemplate(componentV);
+        TitanOperationStatus status;
+        if (!componentParametersView.isIgnoreUsers()) {
+            status = setCreatorFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
 
-		}
-		if (!componentParametersView.isIgnoreProperties()) {
-			status = setPropertiesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
+            status = setLastModifierFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (!componentParametersView.isIgnoreCategories()) {
+            status = setTopologyTempalteCategoriesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
 
-		}
+            }
+        }
+        if (!componentParametersView.isIgnoreArtifacts()) {
+            TitanOperationStatus storageStatus = setAllArtifactsFromGraph(componentV, toscaElement);
+            if (storageStatus != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(storageStatus));
+            }
+        }
+        if (!componentParametersView.isIgnoreComponentInstancesProperties()) {
+            status = setComponentInstancesPropertiesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (!componentParametersView.isIgnoreCapabilities()) {
+            status = setCapabilitiesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (!componentParametersView.isIgnoreRequirements()) {
+            status = setRequirementsFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (!componentParametersView.isIgnoreAllVersions()) {
+            status = setAllVersions(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (!componentParametersView.isIgnoreAdditionalInformation()) {
+            status = setAdditionalInformationFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
 
-		if (!componentParametersView.isIgnoreComponentInstancesInputs()) {
-			status = setComponentInstancesInputsFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        if (!componentParametersView.isIgnoreGroups()) {
+            status = setGroupsFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
 
-			}
-		}
+        }
+        if (!componentParametersView.isIgnorePolicies()) {
+            status = setPoliciesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
 
-		if (!componentParametersView.isIgnoreCapabiltyProperties()) {
-			status = setComponentInstancesCapPropertiesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        if (!componentParametersView.isIgnoreComponentInstances()) {
+            status = setInstGroupsFromGraph(componentV, toscaElement);
 
-			}
-		}
+            //Mark all CIs that has archived origins
+            archiveOperation.setArchivedOriginsFlagInComponentInstances(componentV);
 
-		if (!componentParametersView.isIgnoreForwardingPath()) {
-			status = setForwardingGraphPropertiesFromGraph(componentV, toscaElement);
-			if (status != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
 
-			}
-		}
-		if (!componentParametersView.isIgnoreInterfaces()) {
-			TitanOperationStatus storageStatus = setInterfcesFromGraph(componentV, toscaElement);
-			if (storageStatus != TitanOperationStatus.OK) {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(storageStatus));
-			}
-		}
+        }
+        if (!componentParametersView.isIgnoreInputs()) {
+            status = setInputsFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
 
-		return Either.left(toscaElement);
-	}
+        }
+        if (!componentParametersView.isIgnoreProperties()) {
+            status = setPropertiesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
 
-	private TitanOperationStatus setInterfcesFromGraph(GraphVertex componentV,
-													   TopologyTemplate topologyTemplate) {
-		Either<Map<String, InterfaceDataDefinition>, TitanOperationStatus> result = getDataFromGraph
-				(componentV,
-						EdgeLabelEnum.INTERFACE_ARTIFACTS);
-		if (result.isLeft()) {
-			topologyTemplate.setInterfaces(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+        }
 
-	private StorageOperationStatus associateInterfacesToResource(GraphVertex topologyTemplateVertex,
-																 TopologyTemplate topologyTemplate) {
-		Map<String, InterfaceDataDefinition> interfaces = topologyTemplate.getInterfaces();
-		return associateInterfacesToComponent(topologyTemplateVertex,interfaces);
-	}
+        if (!componentParametersView.isIgnoreComponentInstancesInputs()) {
+            status = setComponentInstancesInputsFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
 
-	public StorageOperationStatus associateInterfacesToComponent(GraphVertex nodeTypeVertex,
-																 Map<String, InterfaceDataDefinition>
-																		 interfaceMap) {
-		if (interfaceMap != null && !interfaceMap.isEmpty()) {
-			Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData
-					(nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfaceMap);
-			if (assosiateElementToData.isRight()) {
-				return assosiateElementToData.right().value();
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+            }
+        }
 
+        if (!componentParametersView.isIgnoreCapabiltyProperties()) {
+            status = setComponentInstancesCapPropertiesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
 
-	private TitanOperationStatus setPoliciesFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
-		Either<Map<String, PolicyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.POLICIES);
-		if (result.isLeft()) {
-			toscaElement.setPolicies(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+            }
+        }
 
-	private TitanOperationStatus setForwardingGraphPropertiesFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
-		Either<Map<String, ForwardingPathDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.FORWARDING_PATH);
-		if (result.isLeft()) {
-			topologyTemplate.setForwardingPaths(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+        if (!componentParametersView.isIgnoreForwardingPath()) {
+            status = setForwardingGraphPropertiesFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
 
+            }
+        }
 
-	private TitanOperationStatus setComponentInstancesCapPropertiesFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
-		Either<Map<String, MapCapabiltyProperty>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES);
-		if (result.isLeft()) {
-			topologyTemplate.setCalculatedCapabilitiesProperties(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+        return Either.left(toscaElement);
+    }
 
-	private TitanOperationStatus setPropertiesFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
-		Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
-		if (result.isLeft()) {
-			toscaElement.setProperties(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setPoliciesFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
+        Either<Map<String, PolicyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.POLICIES);
+        if (result.isLeft()) {
+            toscaElement.setPolicies(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private TitanOperationStatus setInstGroupsFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
-		Either<Map<String, MapGroupsDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INST_GROUPS);
-		if (result.isLeft()) {
-			topologyTemplate.setInstGroups(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setForwardingGraphPropertiesFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
+        Either<Map<String, ForwardingPathDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.FORWARDING_PATH);
+        if (result.isLeft()) {
+            topologyTemplate.setForwardingPaths(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private TitanOperationStatus setComponentInstancesPropertiesFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
-		Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INST_PROPERTIES);
-		if (result.isLeft()) {
-			topologyTemplate.setInstProperties(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
 
-	private TitanOperationStatus setComponentInstancesInputsFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
-		Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INST_INPUTS);
-		if (result.isLeft()) {
-			topologyTemplate.setInstInputs(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setComponentInstancesCapPropertiesFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
+        Either<Map<String, MapCapabilityProperty>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES);
+        if (result.isLeft()) {
+            topologyTemplate.setCalculatedCapabilitiesProperties(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	@Override
-	protected <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
-		Either<Map<String, MapListRequirementDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
-		if (result.isLeft()) {
-			((TopologyTemplate) toscaElement).setCalculatedRequirements(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		result = getDataFromGraph(componentV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
-		if (result.isLeft()) {
-			((TopologyTemplate) toscaElement).setFullfilledRequirements(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
+    private TitanOperationStatus setPropertiesFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
+        Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
+        if (result.isLeft()) {
+            toscaElement.setProperties(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	}
+    private TitanOperationStatus setInstGroupsFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
+        Either<Map<String, MapGroupsDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INST_GROUPS);
+        if (result.isLeft()) {
+            topologyTemplate.setInstGroups(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	protected <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
-		Either<Map<String, MapListCapabiltyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
-		if (result.isLeft()) {
-			((TopologyTemplate) toscaElement).setCalculatedCapabilities(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		result = getDataFromGraph(componentV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
-		if (result.isLeft()) {
-			((TopologyTemplate) toscaElement).setFullfilledCapabilities(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setComponentInstancesPropertiesFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
+        Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INST_PROPERTIES);
+        if (result.isLeft()) {
+            topologyTemplate.setInstProperties(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private TitanOperationStatus setAllArtifactsFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
-		TitanOperationStatus storageStatus = setArtifactsFromGraph(componentV, toscaElement);
-		if (storageStatus != TitanOperationStatus.OK) {
-			return storageStatus;
-		}
-		Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.SERVICE_API_ARTIFACTS);
-		if (result.isLeft()) {
-			toscaElement.setServiceApiArtifacts(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		Either<Map<String, MapArtifactDataDefinition>, TitanOperationStatus> resultInstArt = getDataFromGraph(componentV, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
-		if (resultInstArt.isLeft()) {
-			toscaElement.setInstDeploymentArtifacts(resultInstArt.left().value());
-		} else {
-			if (resultInstArt.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return resultInstArt.right().value();
-			}
-		}
-		Either<Map<String, MapArtifactDataDefinition>, TitanOperationStatus> instanceArt = getDataFromGraph(componentV, EdgeLabelEnum.INSTANCE_ARTIFACTS);
-		if (instanceArt.isLeft()) {
-			toscaElement.setInstanceArtifacts(instanceArt.left().value());
-		} else {
-			if (instanceArt.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return instanceArt.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setComponentInstancesInputsFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
+        Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INST_INPUTS);
+        if (result.isLeft()) {
+            topologyTemplate.setInstInputs(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private TitanOperationStatus setInputsFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
-		Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INPUTS);
-		if (result.isLeft()) {
-			toscaElement.setInputs(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    @Override
+    protected <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
+        Either<Map<String, MapListRequirementDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
+        if (result.isLeft()) {
+            ((TopologyTemplate) toscaElement).setCalculatedRequirements(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        result = getDataFromGraph(componentV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
+        if (result.isLeft()) {
+            ((TopologyTemplate) toscaElement).setFullfilledRequirements(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
 
-	private TitanOperationStatus setGroupsFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
-		Either<Map<String, GroupDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.GROUPS);
-		if (result.isLeft()) {
-			toscaElement.setGroups(result.left().value());
-		} else {
-			if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
-				return result.right().value();
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    }
 
-	private TitanOperationStatus setTopologyTempalteCategoriesFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
-		List<CategoryDefinition> categories = new ArrayList<>();
+    protected <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
+        Either<Map<String, MapListCapabilityDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
+        if (result.isLeft()) {
+            ((TopologyTemplate) toscaElement).setCalculatedCapabilities(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        result = getDataFromGraph(componentV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
+        if (result.isLeft()) {
+            ((TopologyTemplate) toscaElement).setFullfilledCapabilities(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-		switch (componentV.getType()) {
-		case RESOURCE:
-			return setResourceCategoryFromGraph(componentV, toscaElement);
-		case SERVICE:
-			return setServiceCategoryFromGraph(componentV, toscaElement, categories);
+    private TitanOperationStatus setAllArtifactsFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
+        TitanOperationStatus storageStatus = setArtifactsFromGraph(componentV, toscaElement);
+        if (storageStatus != TitanOperationStatus.OK) {
+            return storageStatus;
+        }
+        Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.SERVICE_API_ARTIFACTS);
+        if (result.isLeft()) {
+            toscaElement.setServiceApiArtifacts(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        Either<Map<String, MapArtifactDataDefinition>, TitanOperationStatus> resultInstArt = getDataFromGraph(componentV, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
+        if (resultInstArt.isLeft()) {
+            toscaElement.setInstDeploymentArtifacts(resultInstArt.left().value());
+        } else {
+            if (resultInstArt.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return resultInstArt.right().value();
+            }
+        }
+        Either<Map<String, MapArtifactDataDefinition>, TitanOperationStatus> instanceArt = getDataFromGraph(componentV, EdgeLabelEnum.INSTANCE_ARTIFACTS);
+        if (instanceArt.isLeft()) {
+            toscaElement.setInstanceArtifacts(instanceArt.left().value());
+        } else {
+            if (instanceArt.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return instanceArt.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-		default:
-			log.debug("Not supported component type {} ", componentV.getType());
-			break;
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setInputsFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
+        Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INPUTS);
+        if (result.isLeft()) {
+            toscaElement.setInputs(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private TitanOperationStatus setServiceCategoryFromGraph(GraphVertex componentV, ToscaElement toscaElement, List<CategoryDefinition> categories) {
-		Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
-		if (childVertex.isRight()) {
-			log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, componentV.getUniqueId(), childVertex.right().value());
-			return childVertex.right().value();
-		}
-		GraphVertex categoryV = childVertex.left().value();
-		Map<GraphPropertyEnum, Object> metadataProperties = categoryV.getMetadataProperties();
-		CategoryDefinition category = new CategoryDefinition();
-		category.setUniqueId(categoryV.getUniqueId());
-		category.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
-		category.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
+    private TitanOperationStatus setGroupsFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
+        Either<Map<String, GroupDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.GROUPS);
+        if (result.isLeft()) {
+            toscaElement.setGroups(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-		Type listTypeCat = new TypeToken<List<String>>() {}.getType();
-		List<String> iconsfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS.getProperty()), listTypeCat);
-		category.setIcons(iconsfromJsonCat);
-		categories.add(category);
-		toscaElement.setCategories(categories);
+    private TitanOperationStatus setTopologyTempalteCategoriesFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
+        List<CategoryDefinition> categories = new ArrayList<>();
 
-		return TitanOperationStatus.OK;
-	}
+        switch (componentV.getType()) {
+        case RESOURCE:
+            return setResourceCategoryFromGraph(componentV, toscaElement);
+        case SERVICE:
+            return setServiceCategoryFromGraph(componentV, toscaElement, categories);
 
-	@SuppressWarnings("unchecked")
-	private TopologyTemplate convertToTopologyTemplate(GraphVertex componentV) {
+        default:
+            log.debug("Not supported component type {} ", componentV.getType());
+            break;
+        }
+        return TitanOperationStatus.OK;
+    }
 
-		TopologyTemplate topologyTemplate = super.convertToComponent(componentV);
+    private TitanOperationStatus setServiceCategoryFromGraph(GraphVertex componentV, ToscaElement toscaElement, List<CategoryDefinition> categories) {
+        Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
+        if (childVertex.isRight()) {
+            log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, componentV.getUniqueId(), childVertex.right().value());
+            return childVertex.right().value();
+        }
+        GraphVertex categoryV = childVertex.left().value();
+        Map<GraphPropertyEnum, Object> metadataProperties = categoryV.getMetadataProperties();
+        CategoryDefinition category = new CategoryDefinition();
+        category.setUniqueId(categoryV.getUniqueId());
+        category.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
+        category.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
 
-		Map<String, CompositionDataDefinition> json = (Map<String, CompositionDataDefinition>) componentV.getJson();
-		topologyTemplate.setCompositions(json);
+        Type listTypeCat = new TypeToken<List<String>>() {}.getType();
+        List<String> iconsfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS.getProperty()), listTypeCat);
+        category.setIcons(iconsfromJsonCat);
+        categories.add(category);
+        toscaElement.setCategories(categories);
 
-		return topologyTemplate;
-	}
+        return TitanOperationStatus.OK;
+    }
 
-	@Override
-	public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
-		Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
-		if (nodeType.isRight()) {
-			log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
-			return nodeType;
-		}
-		TitanOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
-		if (status != TitanOperationStatus.OK) {
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_ATTRIBUTES);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate instances attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_PROPERTIES);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate instances properties for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
+    @SuppressWarnings("unchecked")
+    private TopologyTemplate convertToTopologyTemplate(GraphVertex componentV) {
 
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_INPUTS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate instances inputs for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
+        TopologyTemplate topologyTemplate = super.convertToComponent(componentV);
 
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.GROUPS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate groups for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_GROUPS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate instance groups for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INPUTS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate inputs for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_INPUTS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate instance inputs for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CALCULATED_CAPABILITIES);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate calculated capabiliites for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate fullfilled capabilities for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate calculated capabiliites properties for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate calculated requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate full filled requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate instance artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.SERVICE_API_ARTIFACTS);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate service api artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.FORWARDING_PATH);
-		if (status != TitanOperationStatus.OK) {
-			log.debug("Failed to disassociate service api artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
-			Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
+        Map<String, CompositionDataDefinition> json = (Map<String, CompositionDataDefinition>) componentV.getJson();
+        topologyTemplate.setCompositions(json);
 
-		status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INSTANCE_ARTIFACTS);
-		toscaElementVertex.getVertex().remove();
-		log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
+        return topologyTemplate;
+    }
 
-		return nodeType;
-	}
+    @Override
+    public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
+        Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
+        if (nodeType.isRight()) {
+            log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
+            return nodeType;
+        }
+        TitanOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
+        if (status != TitanOperationStatus.OK) {
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_ATTRIBUTES);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate instances attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_PROPERTIES);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate instances properties for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
 
-	@SuppressWarnings("unchecked")
-	@Override
-	public Either<TopologyTemplate, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
-		return createTopologyTemplate((TopologyTemplate) toscaElement);
-	}
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_INPUTS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate instances inputs for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
 
-	@Override
-	protected <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
-		return setTopologyTempalteCategoriesFromGraph(vertexComponent, toscaElement);
-	}
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.GROUPS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate groups for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_GROUPS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate instance groups for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INPUTS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate inputs for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_INPUTS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate instance inputs for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CALCULATED_CAPABILITIES);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate calculated capabiliites for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate fullfilled capabilities for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate calculated capabiliites properties for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate calculated requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate full filled requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate instance artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.SERVICE_API_ARTIFACTS);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate service api artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.FORWARDING_PATH);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate service api artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
 
-	@Override
-	protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
-		// Product isn't supported now!!
-		// TODO add for Product
-		if (toscaElementToUpdate.getComponentType() == ComponentTypeEnum.SERVICE) {
-			return validateServiceCategory(toscaElementToUpdate, elementV);
-		} else {
-			// Resource
-			return validateResourceCategory(toscaElementToUpdate, elementV);
-		}
-	}
+        titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INSTANCE_ARTIFACTS);
+        toscaElementVertex.getVertex().remove();
+        log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
 
-	@Override
-	protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex updateElementV) {
-		// not relevant now for topology template
-		return StorageOperationStatus.OK;
-	}
+        return nodeType;
+    }
 
-	@Override
-	public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
-		fillMetadata(elementV, (TopologyTemplate) toscaElementToUpdate, flag);
-	}
+    @SuppressWarnings("unchecked")
+    @Override
+    public Either<TopologyTemplate, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
+        return createTopologyTemplate((TopologyTemplate) toscaElement);
+    }
 
-	private <T extends ToscaElement> StorageOperationStatus validateServiceCategory(T toscaElementToUpdate, GraphVertex elementV) {
-		StorageOperationStatus status = StorageOperationStatus.OK;
-		List<CategoryDefinition> newCategoryList = toscaElementToUpdate.getCategories();
-		CategoryDefinition newCategory = newCategoryList.get(0);
+    @Override
+    protected <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
+        return setTopologyTempalteCategoriesFromGraph(vertexComponent, toscaElement);
+    }
 
-		Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(elementV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
-		if (childVertex.isRight()) {
-			log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, elementV.getUniqueId(), childVertex.right().value());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
-		}
+    @Override
+    protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
+        // Product isn't supported now!!
+        // TODO add for Product
+        if (toscaElementToUpdate.getComponentType() == ComponentTypeEnum.SERVICE) {
+            return validateServiceCategory(toscaElementToUpdate, elementV);
+        } else {
+            // Resource
+            return validateResourceCategory(toscaElementToUpdate, elementV);
+        }
+    }
 
-		GraphVertex categoryV = childVertex.left().value();
-		Map<GraphPropertyEnum, Object> metadataProperties = categoryV.getMetadataProperties();
-		String categoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
+    @Override
+    protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex updateElementV) {
+        // not relevant now for topology template
+        return StorageOperationStatus.OK;
+    }
 
-		String newCategoryName = newCategory.getName();
-		if (newCategoryName != null && false == newCategoryName.equals(categoryNameCurrent)) {
-			// the category was changed
-			Either<GraphVertex, StorageOperationStatus> getCategoryVertex = categoryOperation.getCategory(newCategoryName, VertexTypeEnum.SERVICE_CATEGORY);
+    @Override
+    public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
+        fillMetadata(elementV, (TopologyTemplate) toscaElementToUpdate, flag);
+    }
 
-			if (getCategoryVertex.isRight()) {
-				return getCategoryVertex.right().value();
-			}
-			GraphVertex newCategoryV = getCategoryVertex.left().value();
-			status = moveCategoryEdge(elementV, newCategoryV);
-			log.debug("Going to update the category of the resource from {} to {}. status is {}", categoryNameCurrent, newCategory, status);
-		}
-		return status;
-	}
+    private <T extends ToscaElement> StorageOperationStatus validateServiceCategory(T toscaElementToUpdate, GraphVertex elementV) {
+        StorageOperationStatus status = StorageOperationStatus.OK;
+        List<CategoryDefinition> newCategoryList = toscaElementToUpdate.getCategories();
+        CategoryDefinition newCategory = newCategoryList.get(0);
 
-	public Either<List<GraphVertex>, TitanOperationStatus> getAllNotDeletedElements() {
-		Map<GraphPropertyEnum, Object> propsHasNot = new HashMap<>();
-		propsHasNot.put(GraphPropertyEnum.IS_DELETED, true);
+        Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(elementV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
+        if (childVertex.isRight()) {
+            log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, elementV.getUniqueId(), childVertex.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
+        }
 
-		Either<List<GraphVertex>, TitanOperationStatus> byCriteria = titanDao.getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, null, propsHasNot, JsonParseFlagEnum.ParseJson);
-		if (byCriteria.isRight()) {
-			log.debug("Failed to fetch all non marked topology templates , propsHasNot {}, error {}", propsHasNot, byCriteria.right().value());
-			return Either.right(byCriteria.right().value());
-		}
-		return Either.left(byCriteria.left().value());
-	}
+        GraphVertex categoryV = childVertex.left().value();
+        Map<GraphPropertyEnum, Object> metadataProperties = categoryV.getMetadataProperties();
+        String categoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
 
-	@SuppressWarnings("unchecked")
-	public boolean isInUse(GraphVertex elementV, List<GraphVertex> allNonDeleted) {
-		for (GraphVertex containerV : allNonDeleted) {
-			Map<String, CompositionDataDefinition> composition = (Map<String, CompositionDataDefinition>) containerV.getJson();
-			if (composition != null) {
-				CompositionDataDefinition instances = composition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
-				if (instances != null && instances.getComponentInstances() != null && !instances.getComponentInstances().isEmpty()) {
-					for (ComponentInstanceDataDefinition ci : instances.getComponentInstances().values()) {
-						if (ci.getComponentUid().equals(elementV.getUniqueId())) {
-							log.debug("The resource {} failed to delete cause in use as component instance UniqueID = {} in {} with UniqueID {}", elementV.getUniqueId(), ci.getUniqueId(), containerV.getType(), containerV.getUniqueId());
-							return true;
-						}
-					}
+        String newCategoryName = newCategory.getName();
+        if (newCategoryName != null && !newCategoryName.equals(categoryNameCurrent)) {
+            // the category was changed
+            Either<GraphVertex, StorageOperationStatus> getCategoryVertex = categoryOperation.getCategory(newCategoryName, VertexTypeEnum.SERVICE_CATEGORY);
 
-				}
-			}
-		}
+            if (getCategoryVertex.isRight()) {
+                return getCategoryVertex.right().value();
+            }
+            GraphVertex newCategoryV = getCategoryVertex.left().value();
+            status = moveCategoryEdge(elementV, newCategoryV);
+            log.debug("Going to update the category of the resource from {} to {}. status is {}", categoryNameCurrent, newCategory, status);
+        }
+        return status;
+    }
 
-		return false;
-	}
+    public Either<GraphVertex, StorageOperationStatus> updateDistributionStatus(String uniqueId, User user, DistributionStatusEnum distributionStatus) {
 
-	@SuppressWarnings("unchecked")
-	public boolean isInUse(String componentId, List<GraphVertex> allNonDeleted) {
-		for (GraphVertex containerV : allNonDeleted) {
-			Map<String, CompositionDataDefinition> composition = (Map<String, CompositionDataDefinition>) containerV.getJson();
-			if (composition != null) {
-				CompositionDataDefinition instances = composition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
-				if (instances != null && instances.getComponentInstances() != null && !instances.getComponentInstances().isEmpty()) {
-					for (ComponentInstanceDataDefinition ci : instances.getComponentInstances().values()) {
-						if (ci.getComponentUid().equals(componentId)) {
-							return true;
-						}
-					}
+        Either<GraphVertex, StorageOperationStatus> result = null;
+        String userId = user.getUserId();
+        Either<GraphVertex, TitanOperationStatus> getRes = findUserVertex(userId);
+        GraphVertex userVertex = null;
+        GraphVertex serviceVertex = null;
+        if (getRes.isRight()) {
+            TitanOperationStatus status = getRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Cannot find user {} in the graph. status is {}", userId, status);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        if (result == null) {
+            userVertex = getRes.left().value();
+            getRes = titanDao.getVertexById(uniqueId, JsonParseFlagEnum.ParseMetadata);
+            if (getRes.isRight()) {
+                TitanOperationStatus status = getRes.right().value();
+                log.debug( "Cannot find service {} in the graph. status is {}", uniqueId, status);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (result == null) {
+            serviceVertex = getRes.left().value();
+            Iterator<Edge> edgeIterator = serviceVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.LAST_DISTRIBUTION_STATE_MODIFIER.name());
+            if (edgeIterator.hasNext()) {
+                log.debug("Remove existing edge from user to component {}. Edge type is {}", userId, uniqueId, EdgeLabelEnum.LAST_DISTRIBUTION_STATE_MODIFIER);
+                edgeIterator.next().remove();
+            }
+        }
+        if (result == null) {
+            TitanOperationStatus status = titanDao.createEdge(userVertex, serviceVertex, EdgeLabelEnum.LAST_DISTRIBUTION_STATE_MODIFIER, null);
+            if (status != TitanOperationStatus.OK) {
+                log.debug( "Failed to associate user {} to component {}. Edge type is {}", userId, uniqueId, EdgeLabelEnum.LAST_DISTRIBUTION_STATE_MODIFIER);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (result == null) {
+            serviceVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, distributionStatus.name());
+            long lastUpdateDate = System.currentTimeMillis();
+            serviceVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, lastUpdateDate);
+            Either<GraphVertex, TitanOperationStatus> updateRes = titanDao.updateVertex(serviceVertex);
+            if (updateRes.isRight()) {
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateRes.right().value()));
+            }
+        }
+        if (result == null) {
+            result = Either.left(serviceVertex);
+        }
+        return result;
+    }
+    /**
+     * Returns list of ComponentInstanceProperty belonging to component instance capability specified by name, type and ownerId
+     * @param componentId
+     * @param instanceId
+     * @param capabilityName
+     * @param capabilityType
+     * @param ownerId
+     * @return
+     */
+    public Either<List<ComponentInstanceProperty>, StorageOperationStatus> getComponentInstanceCapabilityProperties(String componentId, String instanceId, String capabilityName, String capabilityType, String ownerId) {
 
-				}
-			}
-		}
+        Either<List<ComponentInstanceProperty>, StorageOperationStatus> result = null;
+        Map<String, MapCapabilityProperty> mapPropertiesDataDefinition = null;
+        Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(componentId, ToscaElementTypeEnum.TOPOLOGY_TEMPLATE, JsonParseFlagEnum.NoParse);
+        if (componentByLabelAndId.isRight()) {
+            result = Either.right(componentByLabelAndId.right().value());
+        }
+        if(componentByLabelAndId.isLeft()){
+            Either<Map<String, MapCapabilityProperty>, TitanOperationStatus> getDataRes = getDataFromGraph(componentByLabelAndId.left().value(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES);
+            if (getDataRes.isRight()) {
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getDataRes.right().value()));
+            } else {
+                mapPropertiesDataDefinition = getDataRes.left().value();
+            }
+        }
+        if(isNotEmptyMapOfProperties(instanceId, mapPropertiesDataDefinition)){
+            result = Either.left(findComponentInstanceCapabilityProperties(instanceId, capabilityName, capabilityType, ownerId, mapPropertiesDataDefinition.get(instanceId).getMapToscaDataDefinition()));
+        }
+        return result;
+    }
 
-		return false;
-	}
+    public StorageOperationStatus updateComponentInstanceCapabilityProperties(Component containerComponent, String componentInstanceId, MapCapabilityProperty instanceProperties) {
+        return updateToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, instanceProperties, componentInstanceId);
+    }
 
-	public Either<GraphVertex, StorageOperationStatus> updateDistributionStatus(String uniqueId, User user, DistributionStatusEnum distributionStatus) {
 
-		Either<GraphVertex, StorageOperationStatus> result = null;
-		String userId = user.getUserId();
-		Either<GraphVertex, TitanOperationStatus> getRes = findUserVertex(userId);
-		GraphVertex userVertex = null;
-		GraphVertex serviceVertex = null;
-		if (getRes.isRight()) {
-			TitanOperationStatus status = getRes.right().value();
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Cannot find user {} in the graph. status is {}", userId, status);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		if (result == null) {
-			userVertex = getRes.left().value();
-			getRes = titanDao.getVertexById(uniqueId, JsonParseFlagEnum.ParseMetadata);
-			if (getRes.isRight()) {
-				TitanOperationStatus status = getRes.right().value();
-				log.error("Cannot find service {} in the graph. status is {}", uniqueId, status);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (result == null) {
-			serviceVertex = getRes.left().value();
-			Iterator<Edge> edgeIterator = serviceVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.LAST_DISTRIBUTION_STATE_MODIFIER.name());
-			if (edgeIterator.hasNext()) {
-				log.debug("Remove existing edge from user to component {}. Edge type is {}", userId, uniqueId, EdgeLabelEnum.LAST_DISTRIBUTION_STATE_MODIFIER);
-				edgeIterator.next().remove();
-			}
-		}
-		if (result == null) {
-			TitanOperationStatus status = titanDao.createEdge(userVertex, serviceVertex, EdgeLabelEnum.LAST_DISTRIBUTION_STATE_MODIFIER, null);
-			if (status != TitanOperationStatus.OK) {
-				log.error("Failed to associate user {} to component {}. Edge type is {}", userId, uniqueId, EdgeLabelEnum.LAST_DISTRIBUTION_STATE_MODIFIER);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (result == null) {
-			serviceVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, distributionStatus.name());
-			long lastUpdateDate = System.currentTimeMillis();
-			serviceVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, lastUpdateDate);
-			Either<GraphVertex, TitanOperationStatus> updateRes = titanDao.updateVertex(serviceVertex);
-			if (updateRes.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateRes.right().value()));
-			}
-		}
-		if (result == null) {
-			result = Either.left(serviceVertex);
-		}
-		return result;
-	}
-	/**
-	 * Returns list of ComponentInstanceProperty belonging to component instance capability specified by name, type and ownerId
-	 * @param componentId
-	 * @param instanceId
-	 * @param capabilityName
-	 * @param capabilityType
-	 * @param ownerId 
-	 * @return
-	 */
-	public Either<List<ComponentInstanceProperty>, StorageOperationStatus> getComponentInstanceCapabilityProperties(String componentId, String instanceId, String capabilityName, String capabilityType, String ownerId) {
+    private boolean isNotEmptyMapOfProperties(String instanceId, Map<String, MapCapabilityProperty> mapPropertiesDataDefinition) {
+        return  MapUtils.isNotEmpty(mapPropertiesDataDefinition) &&
+                mapPropertiesDataDefinition.get(instanceId) != null &&
+                MapUtils.isNotEmpty(mapPropertiesDataDefinition.get(instanceId).getMapToscaDataDefinition());
+    }
 
-		Either<List<ComponentInstanceProperty>, StorageOperationStatus> result = null;
-		Map<String, MapCapabiltyProperty> mapPropertiesDataDefinition = null;
-		Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(componentId, ToscaElementTypeEnum.TopologyTemplate, JsonParseFlagEnum.NoParse);
-		if (componentByLabelAndId.isRight()) {
-			result = Either.right(componentByLabelAndId.right().value());
-		}
-		if(componentByLabelAndId.isLeft()){
-			Either<Map<String, MapCapabiltyProperty>, TitanOperationStatus> getDataRes = getDataFromGraph(componentByLabelAndId.left().value(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES);
-			if (getDataRes.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getDataRes.right().value()));
-			} else {
-				mapPropertiesDataDefinition = getDataRes.left().value();
-			}
-		}
-		if(isNotEmptyMapOfProperties(instanceId, mapPropertiesDataDefinition)){
-			result = Either.left(findComponentInstanceCapabilityProperties(instanceId, capabilityName, capabilityType, ownerId, mapPropertiesDataDefinition.get(instanceId).getMapToscaDataDefinition()));
-		}
-		return result;
-	}
+    private List<ComponentInstanceProperty> findComponentInstanceCapabilityProperties(String instanceId, String capabilityName, String capabilityType, String ownerId, Map<String, MapPropertiesDataDefinition> propertiesMap) {
+        List<ComponentInstanceProperty> capPropsList = null;
+        for(Entry<String, MapPropertiesDataDefinition> capProp : propertiesMap.entrySet()){
+            if (isBelongingPropertyMap(instanceId, capabilityName, capabilityType, ownerId, capProp)) {
+                Map<String, PropertyDataDefinition> capMap = capProp.getValue().getMapToscaDataDefinition();
+                if (capMap != null && !capMap.isEmpty()) {
+                    capPropsList = capMap.values().stream().map(ComponentInstanceProperty::new).collect(Collectors.toList());
+                    break;
+                }
+            }
+        }
+        if(capPropsList == null){
+            capPropsList = new ArrayList<>();
+        }
+        return capPropsList;
+    }
 
-	public StorageOperationStatus updateComponentInstanceCapabilityProperties(Component containerComponent, String componentInstanceId, MapCapabiltyProperty instanceProperties) {
-		return updateToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, instanceProperties, componentInstanceId);
-	}
+    private boolean isBelongingPropertyMap(String instanceId, String capabilityName, String capabilityType, String ownerId, Entry<String, MapPropertiesDataDefinition> capProp) {
+        if (capProp != null) {
+            String[] path = capProp.getKey().split(ModelConverter.CAP_PROP_DELIM );
+            if (path.length < 4) {
+                log.debug("wrong key format for capabilty, key {}", capProp);
+                return false;
+            }
+            return path[path.length - 2].equals(capabilityType) && path[path.length - 1].equals(capabilityName) && path[1].equals(ownerId) && path[0].equals(instanceId);
+        }
+        return false;
+    }
 
+    public StorageOperationStatus addPolicyToToscaElement(GraphVertex componentV, PolicyDefinition policyDefinition, int counter) {
+        fillPolicyDefinition(componentV, policyDefinition, counter);
+        return addToscaDataToToscaElement(componentV, EdgeLabelEnum.POLICIES, VertexTypeEnum.POLICIES, policyDefinition, JsonPresentationFields.UNIQUE_ID);
+    }
 
-	private boolean isNotEmptyMapOfProperties(String instanceId, Map<String, MapCapabiltyProperty> mapPropertiesDataDefinition) {
-		return  MapUtils.isNotEmpty(mapPropertiesDataDefinition) &&
-				mapPropertiesDataDefinition.get(instanceId) != null &&
-				MapUtils.isNotEmpty(mapPropertiesDataDefinition.get(instanceId).getMapToscaDataDefinition());
-	}
+    public StorageOperationStatus addPoliciesToToscaElement(GraphVertex componentV, List<PolicyDefinition> policies) {
+        return addToscaDataToToscaElement(componentV, EdgeLabelEnum.POLICIES, VertexTypeEnum.POLICIES, policies, JsonPresentationFields.UNIQUE_ID);
+    }
 
-	private List<ComponentInstanceProperty> findComponentInstanceCapabilityProperties(String instanceId, String capabilityName, String capabilityType, String ownerId, Map<String, MapPropertiesDataDefinition> propertiesMap) {
-		List<ComponentInstanceProperty> capPropsList = null;
-		for(Entry<String, MapPropertiesDataDefinition> capProp : propertiesMap.entrySet()){
-			if (isBelongingPropertyMap(instanceId, capabilityName, capabilityType, ownerId, capProp)) {
-				Map<String, PropertyDataDefinition> capMap = capProp.getValue().getMapToscaDataDefinition();
-				if (capMap != null && !capMap.isEmpty()) {
-					capPropsList = capMap.values().stream().map(o -> new ComponentInstanceProperty(o)).collect(Collectors.toList());
-					break;
-				}
-			}
-		}
-		if(capPropsList == null){
-			capPropsList = new ArrayList<>();
-		}
-		return capPropsList;
-	}
+    public StorageOperationStatus updatePolicyOfToscaElement(GraphVertex componentV, PolicyDefinition policyDefinition) {
+        return updateToscaDataOfToscaElement(componentV, EdgeLabelEnum.POLICIES, VertexTypeEnum.POLICIES, policyDefinition, JsonPresentationFields.UNIQUE_ID);
+    }
 
-	private boolean isBelongingPropertyMap(String instanceId, String capabilityName, String capabilityType, String ownerId, Entry<String, MapPropertiesDataDefinition> capProp) {
-		if (capProp != null) {
-			String[] path = capProp.getKey().split(ModelConverter.CAP_PROP_DELIM );
-			if (path.length < 4) {
-				log.debug("wrong key format for capabilty, key {}", capProp);
-				return false;
-			}
-			return path[path.length - 2].equals(capabilityType) && path[path.length - 1].equals(capabilityName) && path[1].equals(ownerId) && path[0].equals(instanceId);
-		}
-		return false;
-	}
+    public StorageOperationStatus updatePoliciesOfToscaElement(GraphVertex componentV, List<PolicyDefinition> policiesDefinitions) {
+        return updateToscaDataOfToscaElement(componentV, EdgeLabelEnum.POLICIES, VertexTypeEnum.POLICIES, policiesDefinitions, JsonPresentationFields.UNIQUE_ID);
+    }
 
-	public StorageOperationStatus addPolicyToToscaElement(GraphVertex componentV, PolicyDefinition policyDefinition, int counter) {
-		fillPolicyDefinition(componentV, policyDefinition, counter);
-		return addToscaDataToToscaElement(componentV, EdgeLabelEnum.POLICIES, VertexTypeEnum.POLICIES, policyDefinition, JsonPresentationFields.UNIQUE_ID);
-	}
-	
-	public StorageOperationStatus updatePolicyOfToscaElement(GraphVertex componentV, PolicyDefinition policyDefinition) {
-		return updateToscaDataOfToscaElement(componentV, EdgeLabelEnum.POLICIES, VertexTypeEnum.POLICIES, policyDefinition, JsonPresentationFields.UNIQUE_ID);
-	}
+    public StorageOperationStatus removePolicyFromToscaElement(GraphVertex componentV, String policyId) {
+        return  deleteToscaDataElement(componentV, EdgeLabelEnum.POLICIES, VertexTypeEnum.POLICIES, policyId, JsonPresentationFields.UNIQUE_ID);
+    }
 
-	public StorageOperationStatus updatePoliciesOfToscaElement(GraphVertex componentV, List<PolicyDefinition> policiesDefinitions) {
-		return updateToscaDataOfToscaElement(componentV, EdgeLabelEnum.POLICIES, VertexTypeEnum.POLICIES, policiesDefinitions, JsonPresentationFields.UNIQUE_ID);
-	}
-	
-	public StorageOperationStatus removePolicyFromToscaElement(GraphVertex componentV, String policyId) {
-		return  deleteToscaDataElement(componentV, EdgeLabelEnum.POLICIES, VertexTypeEnum.POLICIES, policyId, JsonPresentationFields.UNIQUE_ID);
+	public StorageOperationStatus updateGroupOfToscaElement(GraphVertex componentV, GroupDefinition groupDefinition) {
+		return updateToscaDataOfToscaElement(componentV, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groupDefinition, JsonPresentationFields.NAME);
 	}
 
 	private void fillPolicyDefinition(GraphVertex componentV, PolicyDefinition policyDefinition, int counter) {
@@ -1327,8 +1244,176 @@
 	}
 	
 	public static String buildSubComponentName(String componentName, String subComponentTypeName, int counter) {
+        String normalizedComponentName = ValidationUtils.normalizeComponentInstanceName(componentName);
 		String typeSuffix = subComponentTypeName.substring(subComponentTypeName.lastIndexOf('.') + 1, subComponentTypeName.length());
-		return componentName + Constants.GROUP_POLICY_NAME_DELIMETER + typeSuffix + Constants.GROUP_POLICY_NAME_DELIMETER + counter;
+		return normalizedComponentName + Constants.GROUP_POLICY_NAME_DELIMETER + typeSuffix + Constants.GROUP_POLICY_NAME_DELIMETER + counter;
 	}
 
+    void revertNamesOfCalculatedCapabilitiesRequirements(String componentId, TopologyTemplate toscaElement) {
+        if(MapUtils.isNotEmpty(toscaElement.getComponentInstances()) || MapUtils.isNotEmpty(toscaElement.getGroups())){
+            GraphVertex toscaElementV = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse)
+                    .left()
+                    .on(this::throwStorageException);
+            if(MapUtils.isNotEmpty(toscaElement.getComponentInstances())){
+                toscaElement.getComponentInstances().values().forEach(i -> revertNamesOfCalculatedCapabilitiesRequirements(toscaElement, i.getUniqueId()));
+            }
+            if(MapUtils.isNotEmpty(toscaElement.getGroups())){
+                toscaElement.getGroups().values().forEach(g -> revertNamesOfCalculatedCapabilitiesRequirements(toscaElement, g.getUniqueId()));
+            }
+            topologyTemplateOperation.updateFullToscaData(toscaElementV, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES,  toscaElement.getCalculatedCapabilities());
+            topologyTemplateOperation.updateFullToscaData(toscaElementV, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS,  toscaElement.getCalculatedRequirements());
+            topologyTemplateOperation.updateFullToscaData(toscaElementV, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES,  toscaElement.getCalculatedCapabilitiesProperties());
+        }
+    }
+
+    public void updateNamesOfCalculatedCapabilitiesRequirements(String componentId, TopologyTemplate toscaElement) {
+        if(MapUtils.isNotEmpty(toscaElement.getComponentInstances()) || MapUtils.isNotEmpty(toscaElement.getGroups())){
+            GraphVertex toscaElementV = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse)
+                    .left()
+                    .on(this::throwStorageException);
+            if(MapUtils.isNotEmpty(toscaElement.getComponentInstances())){
+                toscaElement.getComponentInstances().values().forEach(i -> updateNamesOfCalculatedCapabilitiesRequirements(toscaElement, i.getUniqueId(), i.getNormalizedName()));
+            }
+            if(MapUtils.isNotEmpty(toscaElement.getGroups())){
+                toscaElement.getGroups().values().forEach(g -> updateNamesOfCalculatedCapabilitiesRequirements(toscaElement, g.getUniqueId(), g.getName()));
+            }
+            topologyTemplateOperation.updateFullToscaData(toscaElementV, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES,  toscaElement.getCalculatedCapabilities());
+            topologyTemplateOperation.updateFullToscaData(toscaElementV, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS,  toscaElement.getCalculatedRequirements());
+            topologyTemplateOperation.updateFullToscaData(toscaElementV, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES,  toscaElement.getCalculatedCapabilitiesProperties());
+        }
+    }
+
+    private void updateNamesOfCalculatedCapabilitiesRequirements(TopologyTemplate toscaElement, String ownerId, String ownerName) {
+        updateCalculatedCapabilitiesNames(toscaElement, ownerId, ownerName);
+        updateCalculatedRequirementsNames(toscaElement, ownerId, ownerName);
+        updateCalculatedCapabilitiesPropertiesKeys(toscaElement, ownerId);
+    }
+
+    private void updateCalculatedCapabilitiesPropertiesKeys(TopologyTemplate toscaElement, String ownerId) {
+        if(toscaElement.getCalculatedCapabilitiesProperties() != null && toscaElement.getCalculatedCapabilitiesProperties().containsKey(ownerId)){
+            MapCapabilityProperty newProps =  new MapCapabilityProperty();
+            toscaElement.getCalculatedCapabilitiesProperties().get(ownerId)
+                    .getMapToscaDataDefinition()
+                    .forEach((k, v)-> updateAndAddCalculatedCapabilitiesProperties(k, v, toscaElement.getCalculatedCapabilities().get(ownerId), newProps));
+            if(MapUtils.isNotEmpty(newProps.getMapToscaDataDefinition())) {
+                toscaElement.getCalculatedCapabilitiesProperties().put(ownerId, newProps);
+            }
+        }
+    }
+
+    private void updateCalculatedRequirementsNames(TopologyTemplate toscaElement, String ownerId, String ownerName) {
+        if(toscaElement.getCalculatedRequirements() != null && toscaElement.getCalculatedRequirements().containsKey(ownerId)){
+            String prefix = ownerName + ".";
+            toscaElement.getCalculatedRequirements().get(ownerId)
+                .getMapToscaDataDefinition().values().stream()
+                .flatMap(l -> l.getListToscaDataDefinition().stream())
+                .forEach(r -> {
+                    if(ComponentUtilities.isNotUpdatedCapReqName(prefix, r.getName(), r.getPreviousName())) {
+                        if(StringUtils.isNotEmpty(r.getPreviousName())){
+                            r.setParentName(r.getPreviousName());
+                        }
+                        r.setPreviousName(r.getName());
+                    }
+                    r.setName(prefix + r.getPreviousName());
+                });
+        }
+    }
+
+    private void updateCalculatedCapabilitiesNames(TopologyTemplate toscaElement, String ownerId, String ownerName) {
+        if(toscaElement.getCalculatedCapabilities() != null && toscaElement.getCalculatedCapabilities().containsKey(ownerId)){
+            String prefix = ownerName + ".";
+            toscaElement.getCalculatedCapabilities().get(ownerId)
+                .getMapToscaDataDefinition().values().stream()
+                .flatMap(l -> l.getListToscaDataDefinition().stream())
+                .forEach(c -> {
+                    if(ComponentUtilities.isNotUpdatedCapReqName(prefix, c.getName(), c.getPreviousName())) {
+                        if(StringUtils.isNotEmpty(c.getPreviousName())){
+                            c.setParentName(c.getPreviousName());
+                        }
+                        c.setPreviousName(c.getName());
+                    }
+                    c.setName(prefix + c.getPreviousName());
+                });
+        }
+    }
+
+    private void updateAndAddCalculatedCapabilitiesProperties(String stringKey, MapPropertiesDataDefinition properties, MapListCapabilityDataDefinition calculatedCapabilities, MapCapabilityProperty newProps) {
+        String[] key = stringKey.split(ModelConverter.CAP_PROP_DELIM);
+        String capType = key[key.length - 2];
+        String capName = key[key.length - 1];
+        Optional<CapabilityDataDefinition> foundCapOpt = calculatedCapabilities.getMapToscaDataDefinition().get(capType)
+                .getListToscaDataDefinition().stream()
+                .filter(c -> c.getPreviousName().equals(capName))
+                .findFirst();
+        if(foundCapOpt.isPresent()){
+            key[key.length - 1] = foundCapOpt.get().getName();
+            newProps.put(buildCaLCapPropKey(key),properties);
+        }
+    }
+
+    private void revertNamesOfCalculatedCapabilitiesRequirements(TopologyTemplate toscaElement, String ownerId) {
+        revertCalculatedCapabilitiesPropertiesKeys(toscaElement, ownerId);
+        revertCalculatedCapabilitiesNames(toscaElement, ownerId);
+        revertCalculatedRequirementsNames(toscaElement, ownerId);
+    }
+
+    private void revertCalculatedCapabilitiesPropertiesKeys(TopologyTemplate toscaElement, String ownerId) {
+        if(toscaElement.getCalculatedCapabilitiesProperties() != null && toscaElement.getCalculatedCapabilitiesProperties().containsKey(ownerId)){
+            MapCapabilityProperty newProps =  new MapCapabilityProperty();
+            toscaElement.getCalculatedCapabilitiesProperties().get(ownerId)
+                    .getMapToscaDataDefinition()
+                    .forEach((k,v) -> revertAndAddCalculatedCapabilitiesProperties(k, v, toscaElement.getCalculatedCapabilities().get(ownerId), newProps));
+            if(MapUtils.isNotEmpty(newProps.getMapToscaDataDefinition())) {
+                toscaElement.getCalculatedCapabilitiesProperties().put(ownerId, newProps);
+            }
+        }
+    }
+
+    private void revertCalculatedRequirementsNames(TopologyTemplate toscaElement, String ownerId) {
+        if(toscaElement.getCalculatedRequirements() != null && toscaElement.getCalculatedRequirements().containsKey(ownerId)){
+            toscaElement.getCalculatedRequirements().get(ownerId)
+                    .getMapToscaDataDefinition().values().stream()
+                    .flatMap(l -> l.getListToscaDataDefinition().stream())
+                    .forEach(r -> {r.setName(r.getPreviousName());r.setPreviousName(r.getParentName());});
+        }
+    }
+
+    private void revertCalculatedCapabilitiesNames(TopologyTemplate toscaElement, String ownerId) {
+        if(toscaElement.getCalculatedCapabilities() != null && toscaElement.getCalculatedCapabilities().containsKey(ownerId)){
+            toscaElement.getCalculatedCapabilities().get(ownerId)
+                    .getMapToscaDataDefinition().values().stream()
+                    .flatMap(l -> l.getListToscaDataDefinition().stream())
+                    .forEach(c -> {c.setName(c.getPreviousName());c.setPreviousName(c.getParentName());});
+        }
+    }
+
+    private void revertAndAddCalculatedCapabilitiesProperties(String stringKey, MapPropertiesDataDefinition properties, MapListCapabilityDataDefinition calculatedCapabilities, MapCapabilityProperty newProps) {
+        String[] key = stringKey.split(ModelConverter.CAP_PROP_DELIM);
+        String capType = key[key.length - 2];
+        String capName = key[key.length - 1];
+        Optional<CapabilityDataDefinition> foundCapOpt = calculatedCapabilities.getMapToscaDataDefinition().get(capType)
+                .getListToscaDataDefinition().stream()
+                .filter(c -> c.getName().equals(capName) && StringUtils.isNotEmpty(c.getPreviousName()))
+                .findFirst();
+        if(foundCapOpt.isPresent()){
+            key[key.length - 1] = foundCapOpt.get().getPreviousName();
+        }
+        newProps.put(buildCaLCapPropKey(key), properties);
+    }
+
+    private String buildCaLCapPropKey(String[] keyArray) {
+        StringBuilder key = new StringBuilder();
+        for(int i = 0; i< keyArray.length; ++i){
+            key.append(keyArray[i]);
+            if(i < keyArray.length - 1){
+                key.append(ModelConverter.CAP_PROP_DELIM);
+            }
+        }
+        return key.toString();
+    }
+
+    private GraphVertex throwStorageException(TitanOperationStatus status) {
+        throw new StorageException(status);
+    }
+
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaDataOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaDataOperation.java
index f30a4d9..0abc011 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaDataOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaDataOperation.java
@@ -20,12 +20,6 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 @org.springframework.stereotype.Component("tosca-data-operation")
 public class ToscaDataOperation extends BaseOperation {
-	
-	private static Logger logger = LoggerFactory.getLogger(ToscaDataOperation.class.getName());
-	
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementLifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementLifecycleOperation.java
index 86415de..d7ff072 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementLifecycleOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementLifecycleOperation.java
@@ -20,15 +20,8 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
@@ -46,15 +39,7 @@
 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.*;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
@@ -73,12 +58,10 @@
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.util.*;
+import java.util.stream.Collectors;
 
 @org.springframework.stereotype.Component("tosca-element-lifecycle-operation")
 
@@ -87,1516 +70,1520 @@
  */
 public class ToscaElementLifecycleOperation extends BaseOperation {
 
+    private static final String FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS = "Failed to delete last state edge. Status is {}. ";
 	private static final String FAILED_TO_GET_VERTICES = "Failed to get vertices by id {}. Status is {}. ";
-	public static final String VERSION_DELIMETER = ".";
-	public static final String VERSION_DELIMETER_REGEXP = "\\.";
+    public static final String VERSION_DELIMITER = ".";
+    public static final String VERSION_DELIMITER_REGEXP = "\\.";
 
-	private static Logger logger = LoggerFactory.getLogger(ToscaElementLifecycleOperation.class.getName());
+    private static final Logger log = Logger.getLogger(ToscaElementLifecycleOperation.class);
 
-	/**
-	 * Performs changing a lifecycle state of tosca element from "checked out" or "ready for certification" to "checked in"
-	 * 
-	 * @param currState
-	 * @param toscaElementId
-	 * @param modifierId
-	 * @param ownerId
-	 * @return
-	 */
-	public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, String toscaElementId, String modifierId, String ownerId) {
-		Either<GraphVertex, StorageOperationStatus> updateResult = null;
-		Either<ToscaElement, StorageOperationStatus> result = null;
-		Map<String, GraphVertex> vertices = null;
-		ToscaElementOperation operation;
-		try {
-			Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckin(toscaElementId, modifierId, ownerId));
-			if (getVerticesRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
-				updateResult = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
-			} else {
-				vertices = getVerticesRes.left().value();
-				updateResult = checkinToscaELement(currState, vertices.get(toscaElementId), vertices.get(ownerId), vertices.get(modifierId), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
-			}
-			if (updateResult.isLeft()) {
-				ComponentParametersView componentParametersView = buildComponentParametersViewAfterCheckin();
-				operation = getToscaElementOperation(vertices.get(toscaElementId).getLabel());
-				result = operation.getToscaElement(updateResult.left().value().getUniqueId(), componentParametersView);
-				if (result.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get updated tosca element {}. Status is {}", toscaElementId, result.right().value());
-				}
-			} else {
-				result = Either.right(updateResult.right().value());
-			}
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during checkin of tosca element {}. {} ", toscaElementId, e.getMessage());
-		}
-		return result;
-	}
+    /**
+     * Performs changing a lifecycle state of tosca element from "checked out" or "ready for certification" to "checked in"
+     * 
+     * @param currState
+     * @param toscaElementId
+     * @param modifierId
+     * @param ownerId
+     * @return
+     */
+    public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, String toscaElementId, String modifierId, String ownerId) {
+        Either<GraphVertex, StorageOperationStatus> updateResult = null;
+        Either<ToscaElement, StorageOperationStatus> result = null;
+        Map<String, GraphVertex> vertices = null;
+        ToscaElementOperation operation;
+        try {
+            Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckin(toscaElementId, modifierId, ownerId));
+            if (getVerticesRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
+                updateResult = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
+            } else {
+                vertices = getVerticesRes.left().value();
+                updateResult = checkinToscaELement(currState, vertices.get(toscaElementId), vertices.get(ownerId), vertices.get(modifierId), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
+            }
+            if (updateResult.isLeft()) {
+                operation = getToscaElementOperation(vertices.get(toscaElementId).getLabel());
+                result = operation.getToscaElement(updateResult.left().value().getUniqueId());
+                if (result.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated tosca element {}. Status is {}", toscaElementId, result.right().value());
+                }
+            } else {
+                result = Either.right(updateResult.right().value());
+            }
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during checkin of tosca element {}. {} ", toscaElementId, e.getMessage());
+        }
+        return result;
+    }
 
-	/**
-	 * Returns vertex presenting owner of tosca element specified by uniqueId
-	 * 
-	 * @param toscaElement
-	 * @return
-	 */
-	public Either<User, StorageOperationStatus> getToscaElementOwner(String toscaElementId) {
-		Either<User, StorageOperationStatus> result = null;
-		GraphVertex toscaElement = null;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
-		if (getToscaElementRes.isRight()) {
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
-		}
-		if (result == null) {
-			toscaElement = getToscaElementRes.left().value();
-			Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
-			if (vertices == null || !vertices.hasNext()) {
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-			} else {
-				result = Either.left(convertToUser(vertices.next()));
-			}
-		}
-		return result;
-	}
+    /**
+     * Returns vertex presenting owner of tosca element specified by uniqueId
+     * 
+     * @param toscaElementId
+     * @return
+     */
+    public Either<User, StorageOperationStatus> getToscaElementOwner(String toscaElementId) {
+        Either<User, StorageOperationStatus> result = null;
+        GraphVertex toscaElement = null;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
+        }
+        if (result == null) {
+            toscaElement = getToscaElementRes.left().value();
+            Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
+            if (vertices == null || !vertices.hasNext()) {
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+            } else {
+                result = Either.left(convertToUser(vertices.next()));
+            }
+        }
+        return result;
+    }
 
-	/**
-	 * Returns vertex presenting owner of tosca element specified by uniqueId
-	 * 
-	 * @param toscaElement
-	 * @return
-	 */
-	public Either<User, StorageOperationStatus> getToscaElementOwner(GraphVertex toscaElement) {
-		Either<User, StorageOperationStatus> result = null;
-		Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
-		if (vertices == null || !vertices.hasNext()) {
-			result = Either.right(StorageOperationStatus.NOT_FOUND);
-		} else {
-			result = Either.left(convertToUser(vertices.next()));
-		}
-		return result;
-	}
+    /**
+     * Returns vertex presenting owner of tosca element specified by uniqueId
+     * 
+     * @param toscaElement
+     * @return
+     */
+    public Either<User, StorageOperationStatus> getToscaElementOwner(GraphVertex toscaElement) {
+        Either<User, StorageOperationStatus> result = null;
+        Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
+        if (vertices == null || !vertices.hasNext()) {
+            result = Either.right(StorageOperationStatus.NOT_FOUND);
+        } else {
+            result = Either.left(convertToUser(vertices.next()));
+        }
+        return result;
+    }
 
-	/**
-	 * Performs checkout of a tosca element
-	 * 
-	 * @param toscaElementId
-	 * @param modifierId
-	 * @param ownerId
-	 * @param currState
-	 * @return
-	 */
-	public Either<ToscaElement, StorageOperationStatus> checkoutToscaElement(String toscaElementId, String modifierId, String ownerId) {
-		Either<ToscaElement, StorageOperationStatus> result = null;
-		Map<String, GraphVertex> vertices = null;
-		try {
-			Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckout(toscaElementId, modifierId, ownerId));
-			if (getVerticesRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
-			}
-			if (result == null) {
-				vertices = getVerticesRes.left().value();
-				// update previous component if not certified
-				StorageOperationStatus status = updatePreviousVersion(vertices.get(toscaElementId), vertices.get(ownerId));
-				if (status != StorageOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update vertex with id {} . Status is {}. ", status);
-					result = Either.right(status);
-				}
-			}
-			if (result == null) {
-				result = cloneToscaElementForCheckout(vertices.get(toscaElementId), vertices.get(modifierId));
-				if (result.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to checkout tosca element {}. Status is {} ", toscaElementId, result.right().value());
-				}
+    /**
+     * Performs checkout of a tosca element
+     * 
+     * @param toscaElementId
+     * @param modifierId
+     * @param ownerId
+     * @return
+     */
+    public Either<ToscaElement, StorageOperationStatus> checkoutToscaElement(String toscaElementId, String modifierId, String ownerId) {
+        Either<ToscaElement, StorageOperationStatus> result = null;
+        Map<String, GraphVertex> vertices = null;
+        try {
+            Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckout(toscaElementId, modifierId, ownerId));
+            if (getVerticesRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
+            }
+            if (result == null) {
+                vertices = getVerticesRes.left().value();
+                // update previous component if not certified
+                StorageOperationStatus status = updatePreviousVersion(vertices.get(toscaElementId), vertices.get(ownerId));
+                if (status != StorageOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update vertex with id {} . Status is {}. ", status);
+                    result = Either.right(status);
+                }
+            }
+            if (result == null) {
+                result = cloneToscaElementForCheckout(vertices.get(toscaElementId), vertices.get(modifierId));
+                if (result.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to checkout tosca element {}. Status is {} ", toscaElementId, result.right().value());
+                }
 
-			}
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during checkout tosca element {}. {}", toscaElementId, e.getMessage());
-		}
-		return result;
-	}
+            }
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during checkout tosca element {}. {}", toscaElementId, e.getMessage());
+        }
+        return result;
+    }
 
-	/**
-	 * Performs undo checkout for tosca element
-	 * 
-	 * @param toscaElementId
-	 * @return
-	 */
-	public Either<ToscaElement, StorageOperationStatus> undoCheckout(String toscaElementId) {
-		Either<ToscaElement, StorageOperationStatus> result = null;
-		Either<GraphVertex, TitanOperationStatus> getToscaElementRes = null;
-		Iterator<Edge> nextVersionComponentIter = null;
-		ToscaElementOperation operation;
-		Vertex preVersionVertex = null;
-		try {
-			getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.ParseMetadata);
-			if (getToscaElementRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
-			}
-			GraphVertex currVersionV = getToscaElementRes.left().value();
-			if (result == null && hasPreviousVersion(currVersionV)) {
-				// find previous version
-				nextVersionComponentIter = currVersionV.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
-				if (nextVersionComponentIter == null || !nextVersionComponentIter.hasNext()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch previous version of tosca element with name {}. ", currVersionV.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString());
-					result = Either.right(StorageOperationStatus.NOT_FOUND);
-				}
-				if (result == null) {
-					preVersionVertex = nextVersionComponentIter.next().outVertex();
-					StorageOperationStatus updateOldResourceResult = updateOldToscaElementBeforeUndoCheckout(preVersionVertex);
-					if (updateOldResourceResult != StorageOperationStatus.OK) {
-						result = Either.right(updateOldResourceResult);
-					}
-				}
-			}
-			if (result == null) {
-				GraphVertex prevVersionV = null;
-				if (preVersionVertex != null) {
-					prevVersionV = new GraphVertex();
-					prevVersionV.setVertex((TitanVertex) preVersionVertex);
-					String uniqueIdPreVer = (String) titanDao.getProperty((TitanVertex) preVersionVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
-					prevVersionV.setUniqueId(uniqueIdPreVer);
-				}
-				StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRoot(prevVersionV, currVersionV);
-				if (updateCatalogRes != StorageOperationStatus.OK) {
-					return Either.right(updateCatalogRes);
-				}
-				operation = getToscaElementOperation(currVersionV.getLabel());
-				result = operation.deleteToscaElement(currVersionV);
-			}
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during undo checkout tosca element {}. {}", toscaElementId, e.getMessage());
-		}
-		return result;
-	}
+    /**
+     * Performs undo checkout for tosca element
+     * 
+     * @param toscaElementId
+     * @return
+     */
+    public Either<ToscaElement, StorageOperationStatus> undoCheckout(String toscaElementId) {
+        Either<ToscaElement, StorageOperationStatus> result = null;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes = null;
+        Iterator<Edge> nextVersionComponentIter = null;
+        ToscaElementOperation operation;
+        Vertex preVersionVertex = null;
+        try {
+            getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.ParseMetadata);
+            if (getToscaElementRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
+            }
+            GraphVertex currVersionV = getToscaElementRes.left().value();
+            if (result == null && hasPreviousVersion(currVersionV)) {
+                // find previous version
+                nextVersionComponentIter = currVersionV.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
+                if (nextVersionComponentIter == null || !nextVersionComponentIter.hasNext()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch previous version of tosca element with name {}. ", currVersionV.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString());
+                    result = Either.right(StorageOperationStatus.NOT_FOUND);
+                }
+                if (result == null) {
+                    preVersionVertex = nextVersionComponentIter.next().outVertex();
+                    StorageOperationStatus updateOldResourceResult = updateOldToscaElementBeforeUndoCheckout(preVersionVertex);
+                    if (updateOldResourceResult != StorageOperationStatus.OK) {
+                        result = Either.right(updateOldResourceResult);
+                    }
+                }
+            }
+            if (result == null) {
+                StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRootByUndoCheckout((TitanVertex) preVersionVertex, currVersionV);
+                if (updateCatalogRes != StorageOperationStatus.OK) {
+                    return Either.right(updateCatalogRes);
+                }
+                operation = getToscaElementOperation(currVersionV.getLabel());
+                result = operation.deleteToscaElement(currVersionV);
+            }
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during undo checkout tosca element {}. {}", toscaElementId, e.getMessage());
+        }
+        return result;
+    }
 
-	private boolean hasPreviousVersion(GraphVertex toscaElementVertex) {
-		boolean hasPreviousVersion = true;
-		String version = (String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION);
-		if (StringUtils.isEmpty(version) || version.equals("0.1"))
-			hasPreviousVersion = false;
-		return hasPreviousVersion;
-	}
+    private boolean hasPreviousVersion(GraphVertex toscaElementVertex) {
+        boolean hasPreviousVersion = true;
+        String version = (String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION);
+        if (StringUtils.isEmpty(version) || version.equals("0.1"))
+            hasPreviousVersion = false;
+        return hasPreviousVersion;
+    }
 
-	/**
-	 * Performs request certification for tosca element
-	 * 
-	 * @param toscaElementId
-	 * @param modifierId
-	 * @param ownerId
-	 * @return
-	 */
-	public Either<ToscaElement, StorageOperationStatus> requestCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
-		Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
-		Either<ToscaElement, StorageOperationStatus> result = null;
-		GraphVertex toscaElement = null;
-		GraphVertex modifier = null;
-		GraphVertex owner;
-		try {
-			Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
-			if (getVerticesRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
-			}
-			if (result == null) {
-				toscaElement = getVerticesRes.left().value().get(toscaElementId);
-				modifier = getVerticesRes.left().value().get(modifierId);
-				owner = getVerticesRes.left().value().get(ownerId);
+    /**
+     * Performs request certification for tosca element
+     * 
+     * @param toscaElementId
+     * @param modifierId
+     * @param ownerId
+     * @return
+     */
+    public Either<ToscaElement, StorageOperationStatus> requestCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
+        Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
+        Either<ToscaElement, StorageOperationStatus> result = null;
+        GraphVertex toscaElement = null;
+        GraphVertex modifier = null;
+        GraphVertex owner;
+        try {
+            Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
+            if (getVerticesRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
+            }
+            if (result == null) {
+                toscaElement = getVerticesRes.left().value().get(toscaElementId);
+                modifier = getVerticesRes.left().value().get(modifierId);
+                owner = getVerticesRes.left().value().get(ownerId);
 
-				StorageOperationStatus status = handleRelationsUponRequestForCertification(toscaElement, modifier, owner);
-				if (status != StorageOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
-				}
-			}
-			if (result == null) {
-				LifecycleStateEnum nextState = LifecycleStateEnum.READY_FOR_CERTIFICATION;
+                StorageOperationStatus status = handleRelationsUponRequestForCertification(toscaElement, modifier, owner);
+                if (status != StorageOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
+                }
+            }
+            if (result == null) {
+                LifecycleStateEnum nextState = LifecycleStateEnum.READY_FOR_CERTIFICATION;
 
-				toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
-				toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+                toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
+                toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
 
-				resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
-				if (resultUpdate.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
-					result = Either.right(resultUpdate.right().value());
-				}
-			}
-			if (result == null) {
-				ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
-				result = operation.getToscaElement(toscaElement.getUniqueId());
-			}
-			return result;
+                resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
+                if (resultUpdate.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
+                    result = Either.right(resultUpdate.right().value());
+                }
+            }
+            if (result == null) {
+                ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
+                result = operation.getToscaElement(toscaElement.getUniqueId());
+            }
+            return result;
 
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
-		}
-		return result;
-	}
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
+        }
+        return result;
+    }
 
-	/**
-	 * Starts certification of tosca element
-	 * 
-	 * @param toscaElementId
-	 * @param modifierId
-	 * @param ownerId
-	 * @return
-	 */
-	public Either<ToscaElement, StorageOperationStatus> startCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
-		Either<ToscaElement, StorageOperationStatus> result = null;
-		Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
-		GraphVertex toscaElement = null;
-		GraphVertex modifier = null;
-		GraphVertex owner;
-		try {
-			Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
-			if (getVerticesRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
-			}
-			if (result == null) {
-				toscaElement = getVerticesRes.left().value().get(toscaElementId);
-				modifier = getVerticesRes.left().value().get(modifierId);
-				owner = getVerticesRes.left().value().get(ownerId);
+    /**
+     * Starts certification of tosca element
+     * 
+     * @param toscaElementId
+     * @param modifierId
+     * @param ownerId
+     * @return
+     */
+    public Either<ToscaElement, StorageOperationStatus> startCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
+        Either<ToscaElement, StorageOperationStatus> result = null;
+        Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
+        GraphVertex toscaElement = null;
+        GraphVertex modifier = null;
+        GraphVertex owner;
+        try {
+            Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
+            if (getVerticesRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
+            }
+            if (result == null) {
+                toscaElement = getVerticesRes.left().value().get(toscaElementId);
+                modifier = getVerticesRes.left().value().get(modifierId);
+                owner = getVerticesRes.left().value().get(ownerId);
 
-				StorageOperationStatus status = handleRelationsUponCertification(toscaElement, modifier, owner);
-				if (status != StorageOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations during certification of tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
-				}
-			}
-			if (result == null) {
-				LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFICATION_IN_PROGRESS;
+                StorageOperationStatus status = handleRelationsUponCertification(toscaElement, modifier, owner);
+                if (status != StorageOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations during certification of tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
+                }
+            }
+            if (result == null) {
+                LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFICATION_IN_PROGRESS;
 
-				toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
-				toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+                toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
+                toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
 
-				resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
-				if (resultUpdate.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Couldn't set lifecycle for component {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
-					result = Either.right(resultUpdate.right().value());
-				}
-			}
-			if (result == null) {
-				ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
-				result = operation.getToscaElement(toscaElement.getUniqueId());
-			}
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during start certification tosca element {}. {}", toscaElementId, e.getMessage());
-		}
-		return result;
-	}
+                resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
+                if (resultUpdate.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Couldn't set lifecycle for component {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
+                    result = Either.right(resultUpdate.right().value());
+                }
+            }
+            if (result == null) {
+                ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
+                result = operation.getToscaElement(toscaElement.getUniqueId());
+            }
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during start certification tosca element {}. {}", toscaElementId, e.getMessage());
+        }
+        return result;
+    }
 
-	public Either<ToscaElement, StorageOperationStatus> certifyToscaElement(String toscaElementId, String modifierId, String ownerId) {
-		Either<ToscaElement, StorageOperationStatus> result = null;
-		Either<GraphVertex, StorageOperationStatus> cloneRes = null;
-		GraphVertex toscaElement = null;
-		GraphVertex modifier = null;
-		GraphVertex certifiedToscaElement = null;
-		Integer majorVersion = null;
+    public Either<ToscaElement, StorageOperationStatus> certifyToscaElement(String toscaElementId, String modifierId, String ownerId) {
+        Either<ToscaElement, StorageOperationStatus> result = null;
+        Either<GraphVertex, StorageOperationStatus> cloneRes = null;
+        GraphVertex toscaElement = null;
+        GraphVertex modifier = null;
+        GraphVertex certifiedToscaElement = null;
+        Integer majorVersion = null;
 
-		StorageOperationStatus status;
-		try {
-			Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
-			if (getVerticesRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
-			}
-			if (result == null) {
-				toscaElement = getVerticesRes.left().value().get(toscaElementId);
-				modifier = getVerticesRes.left().value().get(modifierId);
-				majorVersion = getMajorVersion((String) toscaElement.getMetadataProperty(GraphPropertyEnum.VERSION));
-				status = handleRelationsOfPreviousToscaElementBeforeCertifying(toscaElement, modifier, majorVersion);
-				if (status != StorageOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations of previous tosca element before certifying {}. Status is {}. ", toscaElement.getUniqueId(), status);
-				}
-			}
-			if (result == null) {
-				cloneRes = cloneToscaElementForCertify(toscaElement, modifier, majorVersion);
-				if (cloneRes.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to clone tosca element during certification. ");
-					result = Either.right(cloneRes.right().value());
-				}
-			}
-			if (result == null) {
-				certifiedToscaElement = cloneRes.left().value();
-				status = handleRelationsOfNewestCertifiedToscaElement(toscaElement, certifiedToscaElement);
-				if (status != StorageOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations of newest certified tosca element {}. Status is {}. ", certifiedToscaElement.getUniqueId(), status);
-				}
-			}
-			if (result == null) {
-				return getToscaElementOperation(toscaElement.getLabel()).getToscaElement(certifiedToscaElement.getUniqueId());
-			}
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during certification tosca element {}. {}", toscaElementId, e.getMessage());
-		}
-		return result;
-	}
+        StorageOperationStatus status;
+        try {
+            Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
+            if (getVerticesRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
+            }
+            if (result == null) {
+                toscaElement = getVerticesRes.left().value().get(toscaElementId);
+                modifier = getVerticesRes.left().value().get(modifierId);
+                majorVersion = getMajorVersion((String) toscaElement.getMetadataProperty(GraphPropertyEnum.VERSION));
+                status = handleRelationsOfPreviousToscaElementBeforeCertifying(toscaElement, modifier, majorVersion);
+                if (status != StorageOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations of previous tosca element before certifying {}. Status is {}. ", toscaElement.getUniqueId(), status);
+                }
+            }
+            if (result == null) {
+                cloneRes = cloneToscaElementForCertify(toscaElement, modifier, majorVersion);
+                if (cloneRes.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element during certification. ");
+                    result = Either.right(cloneRes.right().value());
+                }
+            }
+            if (result == null) {
+                certifiedToscaElement = cloneRes.left().value();
+                status = handleRelationsOfNewestCertifiedToscaElement(toscaElement, certifiedToscaElement);
+                if (status != StorageOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations of newest certified tosca element {}. Status is {}. ", certifiedToscaElement.getUniqueId(), status);
+                }
+            }
+            if (result == null) {
+                return getToscaElementOperation(toscaElement.getLabel()).getToscaElement(certifiedToscaElement.getUniqueId());
+            }
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during certification tosca element {}. {}", toscaElementId, e.getMessage());
+        }
+        return result;
+    }
 
-	/**
-	 * Deletes (marks as deleted) all tosca elements according received name and uuid
-	 * 
-	 * @param vertexType
-	 * @param componentType
-	 * @param componentName
-	 * @param uuid
-	 * @return
-	 */
-	public Either<Boolean, StorageOperationStatus> deleteOldToscaElementVersions(VertexTypeEnum vertexType, ComponentTypeEnum componentType, String componentName, String uuid) {
+    /**
+     * Deletes (marks as deleted) all tosca elements according received name and uuid
+     * 
+     * @param vertexType
+     * @param componentType
+     * @param componentName
+     * @param uuid
+     * @return
+     */
+    public Either<Boolean, StorageOperationStatus> deleteOldToscaElementVersions(VertexTypeEnum vertexType, ComponentTypeEnum componentType, String componentName, String uuid) {
 
-		Either<Boolean, StorageOperationStatus> result = null;
-		ToscaElementOperation operation = getToscaElementOperation(componentType);
+        Either<Boolean, StorageOperationStatus> result = null;
+        ToscaElementOperation operation = getToscaElementOperation(componentType);
 
-		try {
-			Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
-			properties.put(GraphPropertyEnum.UUID, uuid);
-			properties.put(GraphPropertyEnum.NAME, componentName);
-			Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes = titanDao.getByCriteria(vertexType, properties, JsonParseFlagEnum.ParseMetadata);
-			if (getToscaElementsRes.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
-			}
-			if (result == null) {
-				result = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
-			}
-			if (result == null) {
-				result = Either.left(true);
-			}
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
-		}
-		return result;
-	}
+        try {
+            Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
+            properties.put(GraphPropertyEnum.UUID, uuid);
+            properties.put(GraphPropertyEnum.NAME, componentName);
+            Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes = titanDao.getByCriteria(vertexType, properties, JsonParseFlagEnum.ParseMetadata);
+            if (getToscaElementsRes.isRight()) {
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
+            }
+            if (result == null) {
+                result = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
+            }
+            if (result == null) {
+                result = Either.left(true);
+            }
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
+        }
+        return result;
+    }
 
-	/**
-	 * Performs cancelation or failure of certification for received tosca element
-	 * 
-	 * @param toscaElementId
-	 * @param modifierId
-	 * @param ownerId
-	 * @param nextState
-	 * @return
-	 */
-	public Either<ToscaElement, StorageOperationStatus> cancelOrFailCertification(String toscaElementId, String modifierId, String ownerId, LifecycleStateEnum nextState) {
-		Either<ToscaElement, StorageOperationStatus> result = null;
-		StorageOperationStatus status;
-		ToscaElementOperation operation = null;
-		GraphVertex toscaElement = null;
-		GraphVertex modifier = null;
-		try {
-			Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
-			if (getVerticesRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
-			}
-			if (result == null) {
-				toscaElement = getVerticesRes.left().value().get(toscaElementId);
-				modifier = getVerticesRes.left().value().get(modifierId);
-				operation = getToscaElementOperation(toscaElement.getLabel());
-				toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
-				toscaElement.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifier.getUniqueId());
-				toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
+    /**
+     * Performs cancelation or failure of certification for received tosca element
+     * 
+     * @param toscaElementId
+     * @param modifierId
+     * @param ownerId
+     * @param nextState
+     * @return
+     */
+    public Either<ToscaElement, StorageOperationStatus> cancelOrFailCertification(String toscaElementId, String modifierId, String ownerId, LifecycleStateEnum nextState) {
+        Either<ToscaElement, StorageOperationStatus> result = null;
+        StorageOperationStatus status;
+        ToscaElementOperation operation = null;
+        GraphVertex toscaElement = null;
+        GraphVertex modifier = null;
+        try {
+            Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
+            if (getVerticesRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
+            }
+            if (result == null) {
+                toscaElement = getVerticesRes.left().value().get(toscaElementId);
+                modifier = getVerticesRes.left().value().get(modifierId);
+                operation = getToscaElementOperation(toscaElement.getLabel());
+                toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+                toscaElement.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifier.getUniqueId());
+                toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
 
-				Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElement);
-				if (updateVertexRes.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update vertex {} . Status is {}. ", toscaElementId, updateVertexRes.right().value());
-					result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertexRes.right().value()));
-				}
-			}
-			if (result == null) {
-				// cancel certification process
-				status = handleRelationsUponCancelCertification(toscaElement, nextState);
-				if (status != StorageOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations upon cancel certification {}. Status is {}. ", toscaElement.getUniqueId(), status);
-				}
-			}
-			if (result == null) {
-				// fail certification
-				status = handleRelationsUponFailCertification(toscaElement, nextState);
-				if (status != StorageOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations upon fail certification {}. Status is {}. ", toscaElement.getUniqueId(), status);
-				}
-			}
-			if (result == null) {
-				result = operation.getToscaElement(toscaElementId);
-			}
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during cancel or fail certification of tosca element {}. {}. ", toscaElementId, e.getMessage());
-		}
-		return result;
-	}
+                Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElement);
+                if (updateVertexRes.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update vertex {} . Status is {}. ", toscaElementId, updateVertexRes.right().value());
+                    result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertexRes.right().value()));
+                }
+            }
+            if (result == null) {
+                // cancel certification process
+                status = handleRelationsUponCancelCertification(toscaElement, nextState);
+                if (status != StorageOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations upon cancel certification {}. Status is {}. ", toscaElement.getUniqueId(), status);
+                }
+            }
+            if (result == null) {
+                // fail certification
+                status = handleRelationsUponFailCertification(toscaElement, nextState);
+                if (status != StorageOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations upon fail certification {}. Status is {}. ", toscaElement.getUniqueId(), status);
+                }
+            }
+            if (result == null) {
+                result = operation.getToscaElement(toscaElementId);
+            }
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during cancel or fail certification of tosca element {}. {}. ", toscaElementId, e.getMessage());
+        }
+        return result;
+    }
 
-	public Either<GraphVertex, TitanOperationStatus> findUser(String userId) {
-		return findUserVertex(userId);
-	}
+    public Either<GraphVertex, TitanOperationStatus> findUser(String userId) {
+        return findUserVertex(userId);
+    }
 
-	private Either<Boolean, StorageOperationStatus> markToscaElementsAsDeleted(ToscaElementOperation operation, List<GraphVertex> toscaElements) {
-		Either<Boolean, StorageOperationStatus> result = Either.left(true);
-		for (GraphVertex resourceToDelete : toscaElements) {
-			if (!((String) resourceToDelete.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())) {
-				Either<GraphVertex, StorageOperationStatus> deleteElementRes = operation.markComponentToDelete(resourceToDelete);
-				if (deleteElementRes.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete tosca element {}. Status is {}. ", resourceToDelete.getUniqueId(), deleteElementRes.right().value());
-					result = Either.right(deleteElementRes.right().value());
-					break;
-				}
-			}
-		}
-		return result;
-	}
+    private Either<Boolean, StorageOperationStatus> markToscaElementsAsDeleted(ToscaElementOperation operation, List<GraphVertex> toscaElements) {
+        Either<Boolean, StorageOperationStatus> result = Either.left(true);
+        for (GraphVertex resourceToDelete : toscaElements) {
+            if (!((String) resourceToDelete.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())) {
+                Either<GraphVertex, StorageOperationStatus> deleteElementRes = operation.markComponentToDelete(resourceToDelete);
+                if (deleteElementRes.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete tosca element {}. Status is {}. ", resourceToDelete.getUniqueId(), deleteElementRes.right().value());
+                    result = Either.right(deleteElementRes.right().value());
+                    break;
+                }
+            }
+        }
+        return result;
+    }
 
-	private StorageOperationStatus handleRelationsOfNewestCertifiedToscaElement(GraphVertex toscaElement, GraphVertex certifiedToscaElement) {
-		StorageOperationStatus result = null;
-		Edge foundEdge = null;
-		Iterator<Edge> certReqUserEdgeIter = null;
-		// add rfc relation to preserve follower information
-		// get user of certification request
-		certReqUserEdgeIter = toscaElement.getVertex().edges(Direction.IN, GraphEdgeLabels.LAST_STATE.name());
-		if (certReqUserEdgeIter == null || !certReqUserEdgeIter.hasNext()) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
-			result = StorageOperationStatus.NOT_FOUND;
-		}
-		if (result == null) {
-			TitanOperationStatus createVersionEdgeStatus = titanDao.createEdge(toscaElement, certifiedToscaElement, EdgeLabelEnum.VERSION, new HashMap<>());
-			if (createVersionEdgeStatus != TitanOperationStatus.OK) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create version edge from last element {} to new certified element {}. status=", toscaElement.getUniqueId(), certifiedToscaElement.getUniqueId(),
-						createVersionEdgeStatus);
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(createVersionEdgeStatus);
-			}
-		}
-		if (result == null) {
+    private StorageOperationStatus handleRelationsOfNewestCertifiedToscaElement(GraphVertex toscaElement, GraphVertex certifiedToscaElement) {
+        StorageOperationStatus result = null;
+        Edge foundEdge = null;
+        Iterator<Edge> certReqUserEdgeIter = null;
+        // add rfc relation to preserve follower information
+        // get user of certification request
+        certReqUserEdgeIter = toscaElement.getVertex().edges(Direction.IN, GraphEdgeLabels.LAST_STATE.name());
+        if (certReqUserEdgeIter == null || !certReqUserEdgeIter.hasNext()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
+            result = StorageOperationStatus.NOT_FOUND;
+        }
+        if (result == null) {
+            TitanOperationStatus createVersionEdgeStatus = titanDao.createEdge(toscaElement, certifiedToscaElement, EdgeLabelEnum.VERSION, new HashMap<>());
+            if (createVersionEdgeStatus != TitanOperationStatus.OK) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create version edge from last element {} to new certified element {}. status=", toscaElement.getUniqueId(), certifiedToscaElement.getUniqueId(),
+                        createVersionEdgeStatus);
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(createVersionEdgeStatus);
+            }
+        }
+        if (result == null) {
+        	if (certReqUserEdgeIter!=null) {
+	            while (certReqUserEdgeIter.hasNext()) {
+	                Edge edge = certReqUserEdgeIter.next();
+	                if (((String) titanDao.getProperty(edge, EdgePropertyEnum.STATE)).equals(LifecycleStateEnum.READY_FOR_CERTIFICATION.name())) {
+	                    foundEdge = edge;
+	                    break;
+	                }
+	
+	            }
+        	}
+            if (foundEdge == null) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
+                result = StorageOperationStatus.NOT_FOUND;
+            }
+        }
+        if (result == null) {
+            TitanOperationStatus createEdgeRes = titanDao.createEdge(foundEdge.outVertex(), certifiedToscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, foundEdge);
+            if (createEdgeRes != TitanOperationStatus.OK) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create rfc relation for component {}. status=", certifiedToscaElement.getUniqueId(), createEdgeRes);
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
+            }
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-			while (certReqUserEdgeIter.hasNext()) {
-				Edge edge = certReqUserEdgeIter.next();
-				if (((String) titanDao.getProperty(edge, EdgePropertyEnum.STATE)).equals(LifecycleStateEnum.READY_FOR_CERTIFICATION.name())) {
-					foundEdge = edge;
-					break;
-				}
+    private StorageOperationStatus handleRelationsUponFailCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
+        StorageOperationStatus result = null;
+        TitanOperationStatus status = null;
+        Edge originEdge;
+        Vertex user = null;
+        if (nextState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN) {
+            // fail certification
+            // delete relation CERTIFICATION_IN_PROGRESS
+            Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
+            properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
 
-			}
-			if (foundEdge == null) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
-				result = StorageOperationStatus.NOT_FOUND;
-			}
-		}
-		if (result == null) {
-			TitanOperationStatus createEdgeRes = titanDao.createEdge(foundEdge.outVertex(), certifiedToscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, foundEdge);
-			if (createEdgeRes != TitanOperationStatus.OK) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create rfc relation for component {}. status=", certifiedToscaElement.getUniqueId(), createEdgeRes);
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+            Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
+            if (deleteResult.isRight()) {
+                status = deleteResult.right().value();
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is {}. ", status);
+                result = StorageOperationStatus.INCONSISTENCY;
+            }
+            if (result == null) {
+                // delete relation READY_FOR_CERTIFICATION
+                properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
+                deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
+                if (deleteResult.isRight()) {
+                    status = deleteResult.right().value();
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS, status);
+                    result = StorageOperationStatus.INCONSISTENCY;
+                }
+            }
+            if (result == null) {
+                // delete relation NOT_CERTIFIED_CHECKIN (in order to change to STATE)
+                properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
+                deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
+                if (deleteResult.isRight()) {
+                    status = deleteResult.right().value();
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS, status);
+                    result = StorageOperationStatus.INCONSISTENCY;
+                }
+            }
+            if (result == null) {
+                // create new STATE relation NOT_CERTIFIED_CHECKIN
+                originEdge = deleteResult.left().value();
+                user = originEdge.outVertex();
+                status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
+                if (status != TitanOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
+                    result = StorageOperationStatus.INCONSISTENCY;
+                }
+            }
+            if (result == null) {
+                // delete relation LAST_MODIFIER (in order to change tester to designer)
+                deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
+                if (status != TitanOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
+                    result = StorageOperationStatus.INCONSISTENCY;
+                }
+            }
+            if (result == null) {
+                // create new LAST_MODIFIER relation
+                originEdge = deleteResult.left().value();
+                status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.LAST_MODIFIER, originEdge);
+                if (status != TitanOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
+                    result = StorageOperationStatus.INCONSISTENCY;
+                }
+            }
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-	private StorageOperationStatus handleRelationsUponFailCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
-		StorageOperationStatus result = null;
-		TitanOperationStatus status = null;
-		Edge originEdge;
-		Vertex user = null;
-		if (nextState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN) {
-			// fail certification
-			// delete relation CERTIFICATION_IN_PROGRESS
-			Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
-			properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
+    private StorageOperationStatus handleRelationsUponCancelCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
+        StorageOperationStatus result = null;
+        Edge originEdge;
+        if (nextState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
+            // delete relation CERTIFICATION_IN_PROGRESS
+            Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
+            properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
+            Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
 
-			Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
-			if (deleteResult.isRight()) {
-				status = deleteResult.right().value();
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is {}. ", status);
-				result = StorageOperationStatus.INCONSISTENCY;
-			}
-			if (result == null) {
-				// delete relation READY_FOR_CERTIFICATION
-				properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
-				deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
-				if (deleteResult.isRight()) {
-					status = deleteResult.right().value();
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", status);
-					result = StorageOperationStatus.INCONSISTENCY;
-				}
-			}
-			if (result == null) {
-				// delete relation NOT_CERTIFIED_CHECKIN (in order to change to STATE)
-				properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
-				deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
-				if (deleteResult.isRight()) {
-					status = deleteResult.right().value();
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", status);
-					result = StorageOperationStatus.INCONSISTENCY;
-				}
-			}
-			if (result == null) {
-				// create new STATE relation NOT_CERTIFIED_CHECKIN
-				originEdge = deleteResult.left().value();
-				user = originEdge.outVertex();
-				status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
-				if (status != TitanOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
-					result = StorageOperationStatus.INCONSISTENCY;
-				}
-			}
-			if (result == null) {
-				// delete relation LAST_MODIFIER (in order to change tester to designer)
-				deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
-				if (status != TitanOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
-					result = StorageOperationStatus.INCONSISTENCY;
-				}
-			}
-			if (result == null) {
-				// create new LAST_MODIFIER relation
-				originEdge = deleteResult.left().value();
-				status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.LAST_MODIFIER, originEdge);
-				if (status != TitanOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
-					result = StorageOperationStatus.INCONSISTENCY;
-				}
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+            if (deleteResult.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is  {}. ", deleteResult.right().value());
+                result = StorageOperationStatus.INCONSISTENCY;
+            }
+            if (result == null) {
+                // delete relation READY_FOR_CERTIFICATION (LAST_STATE)
+                properties.put(GraphPropertyEnum.STATE, nextState);
+                deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
 
-	private StorageOperationStatus handleRelationsUponCancelCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
-		StorageOperationStatus result = null;
-		Edge originEdge;
-		if (nextState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
-			// delete relation CERTIFICATION_IN_PROGRESS
-			Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
-			properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
-			Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
+                if (deleteResult.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS, deleteResult.right().value());
+                    result = StorageOperationStatus.INCONSISTENCY;
+                }
+            }
+            if (result == null) {
+                // create relation READY_FOR_CERTIFICATION (STATE)
+                originEdge = deleteResult.left().value();
+                TitanOperationStatus status = titanDao.createEdge(originEdge.outVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
+                if (status != TitanOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
+                    result = StorageOperationStatus.INCONSISTENCY;
+                }
+            }
+            if (result == null) {
+                result = StorageOperationStatus.OK;
+            }
+        }
+        return result;
+    }
 
-			if (deleteResult.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is  {}. ", deleteResult.right().value());
-				result = StorageOperationStatus.INCONSISTENCY;
-			}
-			if (result == null) {
-				// delete relation READY_FOR_CERTIFICATION (LAST_STATE)
-				properties.put(GraphPropertyEnum.STATE, nextState);
-				deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
+    private StorageOperationStatus handleRelationsOfPreviousToscaElementBeforeCertifying(GraphVertex toscaElement, GraphVertex modifier, Integer majorVersion) {
+        StorageOperationStatus result = null;
+        if (majorVersion > 0) {
+            Either<Vertex, StorageOperationStatus> findRes = findLastCertifiedToscaElementVertex(toscaElement);
+            if (findRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch last certified tosca element {} . Status is {}. ", toscaElement.getMetadataProperty(GraphPropertyEnum.NAME), findRes.right().value());
+                result = findRes.right().value();
+            }
+            if (result == null) {
+                Vertex lastCertifiedVertex = findRes.left().value();
+                Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
+                properties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
+                TitanOperationStatus status = titanDao.updateVertexMetadataPropertiesWithJson(lastCertifiedVertex, properties);
+                if (status != TitanOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version  of tosca element {} to [{}]. Status is {}", toscaElement.getUniqueId(), false, status);
+                    result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+                }
+                // remove previous certified version from the catalog
+                GraphVertex lastCertifiedV = new GraphVertex();
+                lastCertifiedV.setVertex((TitanVertex) lastCertifiedVertex);
+                lastCertifiedV.setUniqueId((String) titanDao.getProperty((TitanVertex) lastCertifiedVertex, GraphPropertyEnum.UNIQUE_ID.getProperty()));
+                StorageOperationStatus res = updateEdgeToCatalogRoot(null, lastCertifiedV);
+                if (res != StorageOperationStatus.OK) {
+                    return res;
+                }
+            }
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-				if (deleteResult.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", deleteResult.right().value());
-					result = StorageOperationStatus.INCONSISTENCY;
-				}
-			}
-			if (result == null) {
-				// create relation READY_FOR_CERTIFICATION (STATE)
-				originEdge = deleteResult.left().value();
-				TitanOperationStatus status = titanDao.createEdge(originEdge.outVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
-				if (status != TitanOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
-					result = StorageOperationStatus.INCONSISTENCY;
-				}
-			}
-			if (result == null) {
-				result = StorageOperationStatus.OK;
-			}
-		}
-		return result;
-	}
+    private StorageOperationStatus handleRelationsUponRequestForCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
+        TitanOperationStatus status;
+        StorageOperationStatus result = null;
 
-	private StorageOperationStatus handleRelationsOfPreviousToscaElementBeforeCertifying(GraphVertex toscaElement, GraphVertex modifier, Integer majorVersion) {
-		StorageOperationStatus result = null;
-		if (majorVersion > 0) {
-			Either<Vertex, StorageOperationStatus> findRes = findLastCertifiedToscaElementVertex(toscaElement);
-			if (findRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch last certified tosca element {} . Status is {}. ", toscaElement.getMetadataProperty(GraphPropertyEnum.NAME), findRes.right().value());
-				result = findRes.right().value();
-			}
-			if (result == null) {
-				Vertex lastCertifiedVertex = findRes.left().value();
-				Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
-				properties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
-				TitanOperationStatus status = titanDao.updateVertexMetadataPropertiesWithJson(lastCertifiedVertex, properties);
-				if (status != TitanOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to set highest version  of tosca element {} to [{}]. Status is {}", toscaElement.getUniqueId(), false, status);
-					result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-				}
-				// remove previous certified version from the catalog
-				GraphVertex lastCertifiedV = new GraphVertex();
-				lastCertifiedV.setVertex((TitanVertex) lastCertifiedVertex);
-				lastCertifiedV.setUniqueId((String) titanDao.getProperty((TitanVertex) lastCertifiedVertex, GraphPropertyEnum.UNIQUE_ID.getProperty()));
-				StorageOperationStatus res = updateEdgeToCatalogRoot(null, lastCertifiedV);
-				if (res != StorageOperationStatus.OK) {
-					return res;
-				}
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+        if (((String) toscaElement.getMetadataProperty(GraphPropertyEnum.STATE)).equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
+            // remove CHECKOUT relation
+            Either<Edge, TitanOperationStatus> deleteRes = titanDao.deleteEdge(owner, toscaElement, EdgeLabelEnum.STATE);
+            if (deleteRes.isRight()) {
+                status = deleteRes.right().value();
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge. Status is {}. ", status);
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+            }
+            if (result == null) {
+                // create CHECKIN relation
+                Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
+                properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
+                status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, properties);
+                if (status != TitanOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
+                    result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+                }
+            }
+        } else {
+            status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
+            if (status != TitanOperationStatus.OK) {
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+            }
+        }
+        if (result == null) {
+            // create RFC relation
+            Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
+            properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
+            status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, properties);
+            if (status != TitanOperationStatus.OK) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+            }
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-	private StorageOperationStatus handleRelationsUponRequestForCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
-		TitanOperationStatus status;
-		StorageOperationStatus result = null;
+    private StorageOperationStatus handleRelationsUponCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
 
-		if (((String) toscaElement.getMetadataProperty(GraphPropertyEnum.STATE)).equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
-			// remove CHECKOUT relation
-			Either<Edge, TitanOperationStatus> deleteRes = titanDao.deleteEdge(owner, toscaElement, EdgeLabelEnum.STATE);
-			if (deleteRes.isRight()) {
-				status = deleteRes.right().value();
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete edge. Status is {}. ", status);
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-			}
-			if (result == null) {
-				// create CHECKIN relation
-				Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
-				properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
-				status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, properties);
-				if (status != TitanOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
-					result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-				}
-			}
-		} else {
-			status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
-			if (status != TitanOperationStatus.OK) {
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-			}
-		}
-		if (result == null) {
-			// create RFC relation
-			Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
-			properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
-			status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, properties);
-			if (status != TitanOperationStatus.OK) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+        StorageOperationStatus result = null;
+        TitanOperationStatus status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
+        if (status != TitanOperationStatus.OK) {
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (result == null) {
+            Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
+            properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
+            status = titanDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
+            if (status != TitanOperationStatus.OK) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+            }
+        }
+        if (result == null) {
+            Either<GraphVertex, StorageOperationStatus> updateRelationsRes = updateLastModifierEdge(toscaElement, owner, modifier);
+            if (updateRelationsRes.isRight()) {
+                result = updateRelationsRes.right().value();
+            }
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-	private StorageOperationStatus handleRelationsUponCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
+    private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertex(GraphVertex toscaElement) {
+        return findLastCertifiedToscaElementVertexRecursively(toscaElement.getVertex());
+    }
 
-		StorageOperationStatus result = null;
-		TitanOperationStatus status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
-		if (status != TitanOperationStatus.OK) {
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (result == null) {
-			Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
-			properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
-			status = titanDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
-			if (status != TitanOperationStatus.OK) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-			}
-		}
-		if (result == null) {
-			Either<GraphVertex, StorageOperationStatus> updateRelationsRes = updateLastModifierEdge(toscaElement, owner, modifier);
-			if (updateRelationsRes.isRight()) {
-				result = updateRelationsRes.right().value();
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+    private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertexRecursively(Vertex vertex) {
+        if (isCertifiedVersion((String) vertex.property(GraphPropertyEnum.VERSION.getProperty()).value())) {
+            return Either.left(vertex);
+        }
+        Iterator<Edge> edgeIter = vertex.edges(Direction.IN, EdgeLabelEnum.VERSION.name());
+        if (!edgeIter.hasNext()) {
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        return findLastCertifiedToscaElementVertexRecursively(edgeIter.next().outVertex());
+    }
 
-	private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertex(GraphVertex toscaElement) {
-		return findLastCertifiedToscaElementVertexRecursively(toscaElement.getVertex());
-	}
+    private boolean isCertifiedVersion(String version) {
+        String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
+        if (Integer.parseInt(versionParts[0]) > 0 && Integer.parseInt(versionParts[1]) == 0) {
+            return true;
+        }
+        return false;
+    }
 
-	private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertexRecursively(Vertex vertex) {
-		if (isCertifiedVersion((String) vertex.property(GraphPropertyEnum.VERSION.getProperty()).value())) {
-			return Either.left(vertex);
-		}
-		Iterator<Edge> edgeIter = vertex.edges(Direction.IN, EdgeLabelEnum.VERSION.name());
-		if (!edgeIter.hasNext()) {
-			return Either.right(StorageOperationStatus.NOT_FOUND);
-		}
-		return findLastCertifiedToscaElementVertexRecursively(edgeIter.next().outVertex());
-	}
+    private StorageOperationStatus updateOldToscaElementBeforeUndoCheckout(Vertex previousVersionToscaElement) {
 
-	private boolean isCertifiedVersion(String version) {
-		String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
-		if (Integer.parseInt(versionParts[0]) > 0 && Integer.parseInt(versionParts[1]) == 0) {
-			return true;
-		}
-		return false;
-	}
+        StorageOperationStatus result = StorageOperationStatus.OK;
+        String previousVersion = (String) previousVersionToscaElement.property(GraphPropertyEnum.VERSION.getProperty()).value();
+        if (!previousVersion.endsWith(".0")) {
+            try {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update vertex of previous version of tosca element", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
 
-	private StorageOperationStatus updateOldToscaElementBeforeUndoCheckout(Vertex previousVersionToscaElement) {
+                Map<String, Object> propertiesToUpdate = new HashMap<>();
+                propertiesToUpdate.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
+                Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap((String) previousVersionToscaElement.property(GraphPropertyEnum.METADATA.getProperty()).value());
+                jsonMetadataMap.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
+                propertiesToUpdate.put(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
 
-		StorageOperationStatus result = StorageOperationStatus.OK;
-		String previousVersion = (String) previousVersionToscaElement.property(GraphPropertyEnum.VERSION.getProperty()).value();
-		if (!previousVersion.endsWith(".0")) {
-			try {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update vertex of previous version of tosca element", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
-
-				Map<String, Object> propertiesToUpdate = new HashMap<>();
-				propertiesToUpdate.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
-				Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap((String) previousVersionToscaElement.property(GraphPropertyEnum.METADATA.getProperty()).value());
-				jsonMetadataMap.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
-				propertiesToUpdate.put(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
-
-				titanDao.setVertexProperties(previousVersionToscaElement, propertiesToUpdate);
+                titanDao.setVertexProperties(previousVersionToscaElement, propertiesToUpdate);
 
-				Iterator<Edge> edgesIter = previousVersionToscaElement.edges(Direction.IN, EdgeLabelEnum.LAST_STATE.name());
-				if (!edgesIter.hasNext()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch last modifier vertex for tosca element {}. ", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
-					result = StorageOperationStatus.NOT_FOUND;
-				} else {
-					Edge lastStateEdge = edgesIter.next();
-					Vertex lastModifier = lastStateEdge.outVertex();
-					TitanOperationStatus replaceRes = titanDao.replaceEdgeLabel(lastModifier, previousVersionToscaElement, lastStateEdge, EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE);
-					if (replaceRes != TitanOperationStatus.OK) {
-						CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to replace label from {} to {}. status = {}", EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE, replaceRes);
-						result = StorageOperationStatus.INCONSISTENCY;
-						if (replaceRes != TitanOperationStatus.INVALID_ID) {
-							result = DaoStatusConverter.convertTitanStatusToStorageStatus(replaceRes);
-						}
-					}
+                Iterator<Edge> edgesIter = previousVersionToscaElement.edges(Direction.IN, EdgeLabelEnum.LAST_STATE.name());
+                if (!edgesIter.hasNext()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch last modifier vertex for tosca element {}. ", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
+                    result = StorageOperationStatus.NOT_FOUND;
+                } else {
+                    Edge lastStateEdge = edgesIter.next();
+                    Vertex lastModifier = lastStateEdge.outVertex();
+                    TitanOperationStatus replaceRes = titanDao.replaceEdgeLabel(lastModifier, previousVersionToscaElement, lastStateEdge, EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE);
+                    if (replaceRes != TitanOperationStatus.OK) {
+                        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to replace label from {} to {}. status = {}", EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE, replaceRes);
+                        result = StorageOperationStatus.INCONSISTENCY;
+                        if (replaceRes != TitanOperationStatus.INVALID_ID) {
+                            result = DaoStatusConverter.convertTitanStatusToStorageStatus(replaceRes);
+                        }
+                    }
 
-				}
-			} catch (Exception e) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during update previous tosca element {} before undo checkout. {} ", e.getMessage());
-			}
-		}
-		return result;
-	}
+                }
+            } catch (Exception e) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during update previous tosca element {} before undo checkout. {} ", e.getMessage());
+            }
+        }
+        return result;
+    }
 
-	private StorageOperationStatus updatePreviousVersion(GraphVertex toscaElementVertex, GraphVertex ownerVertex) {
-		StorageOperationStatus result = null;
-		String ownerId = (String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID);
-		String toscaElementId = toscaElementVertex.getUniqueId();
-		if (!toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
-			toscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
-			Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
-			if (updateVertexRes.isRight()) {
-				TitanOperationStatus titatStatus = updateVertexRes.right().value();
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update tosca element vertex {}. Status is  {}", toscaElementVertex.getUniqueId(), titatStatus);
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus);
-			}
-			Either<Edge, TitanOperationStatus> deleteEdgeRes = null;
-			if (result == null) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to replace edge with label {} to label {} from {} to {}. ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId);
+    private StorageOperationStatus updatePreviousVersion(GraphVertex toscaElementVertex, GraphVertex ownerVertex) {
+        StorageOperationStatus result = null;
+        String ownerId = (String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID);
+        String toscaElementId = toscaElementVertex.getUniqueId();
+        if (!toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
+            toscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
+            Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
+            if (updateVertexRes.isRight()) {
+                TitanOperationStatus titatStatus = updateVertexRes.right().value();
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update tosca element vertex {}. Status is  {}", toscaElementVertex.getUniqueId(), titatStatus);
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus);
+            }
+            Either<Edge, TitanOperationStatus> deleteEdgeRes = null;
+            if (result == null) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to replace edge with label {} to label {} from {} to {}. ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId);
 
-				deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
-				if (deleteEdgeRes.isRight()) {
-					TitanOperationStatus titanStatus = deleteEdgeRes.right().value();
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete edge with label {} from {} to {}. Status is {} ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId, titanStatus);
-					if (!titanStatus.equals(TitanOperationStatus.INVALID_ID)) {
-						result = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
-					} else {
-						result = StorageOperationStatus.INCONSISTENCY;
-					}
-				}
-			}
-			if (result == null) {
-				TitanOperationStatus createEdgeRes = titanDao.createEdge(ownerVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_STATE, deleteEdgeRes.left().value());
-				if (createEdgeRes != TitanOperationStatus.OK) {
-					result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
-				}
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+                deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
+                if (deleteEdgeRes.isRight()) {
+                    TitanOperationStatus titanStatus = deleteEdgeRes.right().value();
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge with label {} from {} to {}. Status is {} ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId, titanStatus);
+                    if (!titanStatus.equals(TitanOperationStatus.INVALID_ID)) {
+                        result = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
+                    } else {
+                        result = StorageOperationStatus.INCONSISTENCY;
+                    }
+                }
+            }
+            if (result == null) {
+                TitanOperationStatus createEdgeRes = titanDao.createEdge(ownerVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_STATE, deleteEdgeRes.left().value());
+                if (createEdgeRes != TitanOperationStatus.OK) {
+                    result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
+                }
+            }
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-	private Either<ToscaElement, StorageOperationStatus> cloneToscaElementForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
+    private Either<ToscaElement, StorageOperationStatus> cloneToscaElementForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
 
-		Either<ToscaElement, StorageOperationStatus> result = null;
-		Either<GraphVertex, StorageOperationStatus> cloneResult = null;
-		ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
-		// check if component with the next version doesn't exist.
-		Iterator<Edge> nextVersionComponentIter = toscaElementVertex.getVertex().edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
-		if (nextVersionComponentIter != null && nextVersionComponentIter.hasNext()) {
-			Vertex nextVersionVertex = nextVersionComponentIter.next().inVertex();
-			String fetchedVersion = (String) nextVersionVertex.property(GraphPropertyEnum.VERSION.getProperty()).value();
-			String fetchedName = (String) nextVersionVertex.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()).value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to checkout component {} with version {}. The component with name {} and version {} was fetched from graph as existing following version. ",
-					toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString(), toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION).toString(), fetchedName, fetchedVersion);
-			result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
-		}
-		if (result == null) {
-			cloneResult = operation.cloneToscaElement(toscaElementVertex, cloneGraphVertexForCheckout(toscaElementVertex, modifierVertex), modifierVertex);
-			if (cloneResult.isRight()) {
-				result = Either.right(cloneResult.right().value());
-			}
-		}
-		GraphVertex clonedVertex = null;
-		if (result == null) {
-			clonedVertex = cloneResult.left().value();
-			TitanOperationStatus status = titanDao.createEdge(toscaElementVertex.getVertex(), cloneResult.left().value().getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
-			if (status != TitanOperationStatus.OK) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
-						toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), cloneResult.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
-		}
-		if (result == null) {
-			Boolean isHighest = (Boolean) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
-			GraphVertex prevVersionInCatalog = (isHighest != null && isHighest) ? null : toscaElementVertex;
-			StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRoot(clonedVertex, prevVersionInCatalog);
-			if (updateCatalogRes != StorageOperationStatus.OK) {
-				return Either.right(updateCatalogRes);
-			}
-			result = operation.getToscaElement(cloneResult.left().value().getUniqueId());
-			if (result.isRight()) {
-				return result;
-			}
-			ToscaElement toscaElement = result.left().value();
-			if (toscaElement.getToscaType() == ToscaElementTypeEnum.TopologyTemplate) {
-				result = handleFixTopologyTemplate(toscaElementVertex, result, operation, clonedVertex, toscaElement);
-			}
-		}
+        Either<ToscaElement, StorageOperationStatus> result = null;
+        Either<GraphVertex, StorageOperationStatus> cloneResult = null;
+        ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
+        // check if component with the next version doesn't exist.
+        Iterator<Edge> nextVersionComponentIter = toscaElementVertex.getVertex().edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
+        if (nextVersionComponentIter != null && nextVersionComponentIter.hasNext()) {
+            Vertex nextVersionVertex = nextVersionComponentIter.next().inVertex();
+            String fetchedVersion = (String) nextVersionVertex.property(GraphPropertyEnum.VERSION.getProperty()).value();
+            String fetchedName = (String) nextVersionVertex.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()).value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to checkout component {} with version {}. The component with name {} and version {} was fetched from graph as existing following version. ",
+                    toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString(), toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION).toString(), fetchedName, fetchedVersion);
+            result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
+        }
+        if (result == null) {
+            toscaElementVertex.getOrSetDefaultInstantiationTypeForToscaElementJson();
+            cloneResult = operation.cloneToscaElement(toscaElementVertex, cloneGraphVertexForCheckout(toscaElementVertex, modifierVertex), modifierVertex);
+            if (cloneResult.isRight()) {
+                result = Either.right(cloneResult.right().value());
+            }
+        }
+        GraphVertex clonedVertex = null;
+        if (result == null) {
+            clonedVertex = cloneResult.left().value();
+            TitanOperationStatus status = titanDao.createEdge(toscaElementVertex.getVertex(), cloneResult.left().value().getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
+            if (status != TitanOperationStatus.OK) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
+                        toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), cloneResult.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
+        }
+        if (result == null) {
+            Boolean isHighest = (Boolean) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
+            GraphVertex prevVersionInCatalog = (isHighest != null && isHighest) ? null : toscaElementVertex;
+            StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRoot(clonedVertex, prevVersionInCatalog);
+            if (updateCatalogRes != StorageOperationStatus.OK) {
+                return Either.right(updateCatalogRes);
+            }
+            result = operation.getToscaElement(cloneResult.left().value().getUniqueId());
+            if (result.isRight()) {
+                return result;
+            }
+            ToscaElement toscaElement = result.left().value();
+            if (toscaElement.getToscaType() == ToscaElementTypeEnum.TOPOLOGY_TEMPLATE) {
+                result = handleFixTopologyTemplate(toscaElementVertex, result, operation, clonedVertex, toscaElement);
+            }
+        }
 
-		return result;
-	}
+        return result;
+    }
 
-	private Either<ToscaElement, StorageOperationStatus> handleFixTopologyTemplate(GraphVertex toscaElementVertex, Either<ToscaElement, StorageOperationStatus> result, ToscaElementOperation operation, GraphVertex clonedVertex,
-			ToscaElement toscaElement) {
-		TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
-		Map<String, MapPropertiesDataDefinition> instInputs = topologyTemplate.getInstInputs();
-		Map<String, MapGroupsDataDefinition> instGroups = topologyTemplate.getInstGroups();
-		Map<String, MapArtifactDataDefinition> instArtifactsMap = topologyTemplate.getInstanceArtifacts();
-		Map<String, ToscaElement> origCompMap = new HashMap<>();
-		if (instInputs == null) {
-			instInputs = new HashMap<>();
-		}
-		if (instGroups == null) {
-			instGroups = new HashMap<>();
-		}
-		if (instArtifactsMap == null) {
-			instArtifactsMap = new HashMap<>();
-		}
-		Map<String, ComponentInstanceDataDefinition> instancesMap = topologyTemplate.getComponentInstances();
-		boolean isAddInstGroup = instGroups == null || instGroups.isEmpty();
-		boolean needUpdateComposition = false;
+    private Either<ToscaElement, StorageOperationStatus> handleFixTopologyTemplate(GraphVertex toscaElementVertex, Either<ToscaElement, StorageOperationStatus> result, ToscaElementOperation operation, GraphVertex clonedVertex,
+            ToscaElement toscaElement) {
+        TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
+        Map<String, MapPropertiesDataDefinition> instInputs = topologyTemplate.getInstInputs();
+        Map<String, MapGroupsDataDefinition> instGroups = topologyTemplate.getInstGroups();
+        Map<String, MapArtifactDataDefinition> instArtifactsMap = topologyTemplate.getInstanceArtifacts();
+        Map<String, ToscaElement> origCompMap = new HashMap<>();
+        if (instInputs == null) {
+            instInputs = new HashMap<>();
+        }
+        if (instGroups == null) {
+            instGroups = new HashMap<>();
+        }
+        if (instArtifactsMap == null) {
+            instArtifactsMap = new HashMap<>();
+        }
+        Map<String, ComponentInstanceDataDefinition> instancesMap = topologyTemplate.getComponentInstances();
+        boolean isAddInstGroup = instGroups == null || instGroups.isEmpty();
+        boolean needUpdateComposition = false;
 
-		if (instancesMap != null && !instancesMap.isEmpty()) {
-			for (ComponentInstanceDataDefinition vfInst : instancesMap.values()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "vfInst name is {} . OriginType {}. ", vfInst.getName(), vfInst.getOriginType());
-				if (vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
-					collectInstanceInputAndGroups(instInputs, instGroups, instArtifactsMap, origCompMap, isAddInstGroup, vfInst, clonedVertex);
-				}
-				needUpdateComposition = needUpdateComposition || fixToscaComponentName(vfInst, origCompMap);
-				if (needUpdateComposition) {
-					instancesMap.put(vfInst.getUniqueId(), vfInst);
-				}
-			}
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before add to graph instInputs {}  instGroups {} needUpdateComposition {}", instInputs, instGroups, needUpdateComposition);
-			if (!instInputs.isEmpty()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before add inst inputs {} ", instInputs == null ? 0 : instInputs.size());
-				GraphVertex toscaDataVertex = null;
-				Either<GraphVertex, TitanOperationStatus> instInpVertexEither = titanDao.getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_INPUTS, JsonParseFlagEnum.ParseJson);
-				if (instInpVertexEither.isLeft()) {
-					toscaDataVertex = instInpVertexEither.left().value();
-				}
+        if (instancesMap != null && !instancesMap.isEmpty()) {
+            for (ComponentInstanceDataDefinition vfInst : instancesMap.values()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "vfInst name is {} . OriginType {}. ", vfInst.getName(), vfInst.getOriginType());
+                if (vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
+                    collectInstanceInputAndGroups(instInputs, instGroups, instArtifactsMap, origCompMap, isAddInstGroup, vfInst, clonedVertex);
+                }
+                needUpdateComposition = needUpdateComposition || fixToscaComponentName(vfInst, origCompMap);
+                if (needUpdateComposition) {
+                    instancesMap.put(vfInst.getUniqueId(), vfInst);
+                }
+            }
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add to graph instInputs {}  instGroups {} needUpdateComposition {}", instInputs, instGroups, needUpdateComposition);
+            if (!instInputs.isEmpty()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add inst inputs {} ", instInputs == null ? 0 : instInputs.size());
+                GraphVertex toscaDataVertex = null;
+                Either<GraphVertex, TitanOperationStatus> instInpVertexEither = titanDao.getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_INPUTS, JsonParseFlagEnum.ParseJson);
+                if (instInpVertexEither.isLeft()) {
+                    toscaDataVertex = instInpVertexEither.left().value();
+                }
 
-				StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, toscaDataVertex, instInputs);
-				if (status != StorageOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update instance inputs . Status is {}. ", status);
-					result = Either.right(status);
-					return result;
-				}
+                StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, toscaDataVertex, instInputs);
+                if (status != StorageOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instance inputs . Status is {}. ", status);
+                    result = Either.right(status);
+                    return result;
+                }
 
-			}
-			if (!instGroups.isEmpty()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before add inst groups {} ", instGroups == null ? 0 : instGroups.size());
-				GraphVertex toscaDataVertex = null;
-				Either<GraphVertex, TitanOperationStatus> instGrVertexEither = titanDao.getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_GROUPS, JsonParseFlagEnum.ParseJson);
-				if (instGrVertexEither.isLeft()) {
-					toscaDataVertex = instGrVertexEither.left().value();
-				}
+            }
+            if (!instGroups.isEmpty()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add inst groups {} ", instGroups == null ? 0 : instGroups.size());
+                GraphVertex toscaDataVertex = null;
+                Either<GraphVertex, TitanOperationStatus> instGrVertexEither = titanDao.getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_GROUPS, JsonParseFlagEnum.ParseJson);
+                if (instGrVertexEither.isLeft()) {
+                    toscaDataVertex = instGrVertexEither.left().value();
+                }
 
-				StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, toscaDataVertex, instGroups);
-				if (status != StorageOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update instance group . Status is {}. ", status);
-					result = Either.right(status);
-					return result;
-				}
+                StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, toscaDataVertex, instGroups);
+                if (status != StorageOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instance group . Status is {}. ", status);
+                    result = Either.right(status);
+                    return result;
+                }
 
-			}
-			if (needUpdateComposition) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before update Instances ");
-				Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) clonedVertex.getJson();
-				CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
-				compositionDataDefinition.setComponentInstances(instancesMap);
-				Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(clonedVertex);
-				if (updateElement.isRight()) {
-					TitanOperationStatus status = updateElement.right().value();
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update instances on metadata vertex . Status is {}. ", status);
-					result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-					return result;
-				}
-			}
+            }
+            if (needUpdateComposition) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before update Instances ");
+                Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) clonedVertex.getJson();
+                CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
+                compositionDataDefinition.setComponentInstances(instancesMap);
+                Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(clonedVertex);
+                if (updateElement.isRight()) {
+                    TitanOperationStatus status = updateElement.right().value();
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instances on metadata vertex . Status is {}. ", status);
+                    result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+                    return result;
+                }
+            }
 
-			result = operation.getToscaElement(clonedVertex.getUniqueId());
+            result = operation.getToscaElement(clonedVertex.getUniqueId());
 
-		} else {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "RI map empty on component {}", toscaElement.getUniqueId());
-		}
-		return result;
-	}
+        } else {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "RI map empty on component {}", toscaElement.getUniqueId());
+        }
+        return result;
+    }
 
-	// TODO remove after jsonModelMigration
-	public boolean resolveToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
-		return fixToscaComponentName(vfInst, origCompMap);
-	}
+    // TODO remove after jsonModelMigration
+    public boolean resolveToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
+        return fixToscaComponentName(vfInst, origCompMap);
+    }
 
-	private boolean fixToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
-		if (vfInst.getToscaComponentName() == null || vfInst.getToscaComponentName().isEmpty()) {
-			String ciUid = vfInst.getUniqueId();
-			String origCompUid = vfInst.getComponentUid();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "fixToscaComponentName:: Ri id {} . origin component id is {}. type is{} ", ciUid, origCompUid, vfInst.getOriginType());
-			ToscaElement origComp = null;
-			if (!origCompMap.containsKey(origCompUid)) {
-				Either<ToscaElement, StorageOperationStatus> origCompEither;
-				if (vfInst.getOriginType() == null || vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
-					origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
-				} else {
-					origCompEither = nodeTypeOperation.getToscaElement(origCompUid);
-				}
-				if (origCompEither.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
-					return false;
-				}
-				origComp = origCompEither.left().value();
-				origCompMap.put(origCompUid, origComp);
-			} else {
-				origComp = origCompMap.get(origCompUid);
-			}
-			String toscaName = (String) origComp.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME);
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Origin component id is {}. toscaName {}", origCompUid, toscaName);
-			vfInst.setToscaComponentName(toscaName);
-			return true;
-		}
-		return false;
-	}
+    private boolean fixToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
+        if (vfInst.getToscaComponentName() == null || vfInst.getToscaComponentName().isEmpty()) {
+            String ciUid = vfInst.getUniqueId();
+            String origCompUid = vfInst.getComponentUid();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "fixToscaComponentName:: Ri id {} . origin component id is {}. type is{} ", ciUid, origCompUid, vfInst.getOriginType());
+            ToscaElement origComp = null;
+            if (!origCompMap.containsKey(origCompUid)) {
+                Either<ToscaElement, StorageOperationStatus> origCompEither;
+                if (vfInst.getOriginType() == null || vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
+                    origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
+                } else {
+                    origCompEither = nodeTypeOperation.getToscaElement(origCompUid);
+                }
+                if (origCompEither.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
+                    return false;
+                }
+                origComp = origCompEither.left().value();
+                origCompMap.put(origCompUid, origComp);
+            } else {
+                origComp = origCompMap.get(origCompUid);
+            }
+            String toscaName = (String) origComp.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME);
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Origin component id is {}. toscaName {}", origCompUid, toscaName);
+            vfInst.setToscaComponentName(toscaName);
+            return true;
+        }
+        return false;
+    }
 
-	private void collectInstanceInputAndGroups(Map<String, MapPropertiesDataDefinition> instInputs, Map<String, MapGroupsDataDefinition> instGroups, Map<String, MapArtifactDataDefinition> instArtifactsMap, Map<String, ToscaElement> origCompMap,
-			boolean isAddInstGroup, ComponentInstanceDataDefinition vfInst, GraphVertex clonedVertex) {
-		String ciUid = vfInst.getUniqueId();
-		String origCompUid = vfInst.getComponentUid();
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "collectInstanceInputAndGroups:: Ri id {} . origin component id is {}. ", ciUid, origCompUid);
-		TopologyTemplate origComp = null;
-		if (!origCompMap.containsKey(origCompUid)) {
-			Either<ToscaElement, StorageOperationStatus> origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
-			if (origCompEither.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
-				return;
-			}
-			origComp = (TopologyTemplate) origCompEither.left().value();
-			origCompMap.put(origCompUid, origComp);
-		} else {
-			origComp = (TopologyTemplate) origCompMap.get(origCompUid);
-		}
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Orig component {}. ", origComp.getUniqueId());
+    private void collectInstanceInputAndGroups(Map<String, MapPropertiesDataDefinition> instInputs, Map<String, MapGroupsDataDefinition> instGroups, Map<String, MapArtifactDataDefinition> instArtifactsMap, Map<String, ToscaElement> origCompMap,
+            boolean isAddInstGroup, ComponentInstanceDataDefinition vfInst, GraphVertex clonedVertex) {
+        String ciUid = vfInst.getUniqueId();
+        String origCompUid = vfInst.getComponentUid();
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "collectInstanceInputAndGroups:: Ri id {} . origin component id is {}. ", ciUid, origCompUid);
+        TopologyTemplate origComp = null;
+        if (!origCompMap.containsKey(origCompUid)) {
+            Either<ToscaElement, StorageOperationStatus> origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
+            if (origCompEither.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
+                return;
+            }
+            origComp = (TopologyTemplate) origCompEither.left().value();
+            origCompMap.put(origCompUid, origComp);
+        } else {
+            origComp = (TopologyTemplate) origCompMap.get(origCompUid);
+        }
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Orig component {}. ", origComp.getUniqueId());
 
-		Map<String, PropertyDataDefinition> origInputs = origComp.getInputs();
-		CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Orig component inputs size {}. ", origInputs == null ? 0 : origInputs.size());
-		if (origInputs != null) {
-			if (!instInputs.containsKey(ciUid)) {
-				MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(origInputs);
-				instInputs.put(ciUid, instProperties);
-			} else {
+        Map<String, PropertyDataDefinition> origInputs = origComp.getInputs();
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Orig component inputs size {}. ", origInputs == null ? 0 : origInputs.size());
+        if (origInputs != null) {
+            if (!instInputs.containsKey(ciUid)) {
+                MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(origInputs);
+                instInputs.put(ciUid, instProperties);
+            } else {
 
-				MapPropertiesDataDefinition instInputMap = instInputs.get(ciUid);
-				Map<String, PropertyDataDefinition> instProp = instInputMap.getMapToscaDataDefinition();
-				origInputs.forEach((propName, propMap) -> {
-					if (!instProp.containsKey(propName)) {
-						instProp.put(propName, propMap);
-					}
-				});
-			}
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "ComponentInstanseInputs {}. ", instInputs.get(ciUid));
-		}
+                MapPropertiesDataDefinition instInputMap = instInputs.get(ciUid);
+                Map<String, PropertyDataDefinition> instProp = instInputMap.getMapToscaDataDefinition();
+                origInputs.forEach((propName, propMap) -> {
+                    if (!instProp.containsKey(propName)) {
+                        instProp.put(propName, propMap);
+                    }
+                });
+            }
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "ComponentInstanseInputs {}. ", instInputs.get(ciUid));
+        }
 
-		if (isAddInstGroup) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before create group instance. ");
-			List<GroupDataDefinition> filteredGroups = null;
+        if (isAddInstGroup) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before create group instance. ");
+            List<GroupDataDefinition> filteredGroups = null;
 
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check vf groups before filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
-			if (origComp.getGroups() != null && !origComp.getGroups().isEmpty()) {
-				filteredGroups = origComp.getGroups().values().stream().filter(g -> g.getType().equals(VF_MODULE)).collect(Collectors.toList());
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check vf groups . Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
-			}
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check vf groups after filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
-			if (CollectionUtils.isNotEmpty(filteredGroups)) {
-				MapArtifactDataDefinition instArifacts = null;
-				if (!instArtifactsMap.containsKey(ciUid)) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups before filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
+            if (origComp.getGroups() != null && !origComp.getGroups().isEmpty()) {
+                filteredGroups = origComp.getGroups().values().stream().filter(g -> g.getType().equals(VF_MODULE)).collect(Collectors.toList());
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups . Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
+            }
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups after filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
+            if (CollectionUtils.isNotEmpty(filteredGroups)) {
+                MapArtifactDataDefinition instArifacts = null;
+                if (!instArtifactsMap.containsKey(ciUid)) {
 
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "istance artifacts not found ");
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "istance artifacts not found ");
 
-					Map<String, ArtifactDataDefinition> deploymentArtifacts = origComp.getDeploymentArtifacts();
+                    Map<String, ArtifactDataDefinition> deploymentArtifacts = origComp.getDeploymentArtifacts();
 
-					instArifacts = new MapArtifactDataDefinition(deploymentArtifacts);
-					addToscaDataDeepElementsBlockToToscaElement(clonedVertex, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, instArifacts, ciUid);
+                    instArifacts = new MapArtifactDataDefinition(deploymentArtifacts);
+                    addToscaDataDeepElementsBlockToToscaElement(clonedVertex, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, instArifacts, ciUid);
 
-					instArtifactsMap.put(ciUid, instArifacts);
+                    instArtifactsMap.put(ciUid, instArifacts);
 
-				} else {
-					instArifacts = instArtifactsMap.get(ciUid);
-				}
+                } else {
+                    instArifacts = instArtifactsMap.get(ciUid);
+                }
 
-				if (instArifacts != null) {
-					Map<String, ArtifactDataDefinition> instDeplArtifMap = instArifacts.getMapToscaDataDefinition();
+                if (instArifacts != null) {
+                    Map<String, ArtifactDataDefinition> instDeplArtifMap = instArifacts.getMapToscaDataDefinition();
 
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check group dep artifacts. Size is {} ", instDeplArtifMap == null ? 0 : instDeplArtifMap.values().size());
-					Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
-					for (GroupDataDefinition group : filteredGroups) {
-						CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "create new groupInstance  {} ", group.getName());
-						GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition(group, vfInst, instDeplArtifMap);
-						List<String> artifactsUid = new ArrayList<>();
-						List<String> artifactsId = new ArrayList<>();
-						for (ArtifactDataDefinition artifact : instDeplArtifMap.values()) {
-							// CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "create new groupInstance {} ", artifact.getA);
-							Optional<String> op = group.getArtifacts().stream().filter(p -> p.equals(artifact.getGeneratedFromId())).findAny();
-							if (op.isPresent()) {
-								artifactsUid.add(artifact.getArtifactUUID());
-								artifactsId.add(artifact.getUniqueId());
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check group dep artifacts. Size is {} ", instDeplArtifMap == null ? 0 : instDeplArtifMap.values().size());
+                    Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
+                    for (GroupDataDefinition group : filteredGroups) {
+                        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "create new groupInstance  {} ", group.getName());
+                        GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition(group, vfInst, instDeplArtifMap);
+                        List<String> artifactsUid = new ArrayList<>();
+                        List<String> artifactsId = new ArrayList<>();
+                        if (instDeplArtifMap!=null) {
+	                        for (ArtifactDataDefinition artifact : instDeplArtifMap.values()) {
+	                            Optional<String> op = group.getArtifacts().stream().filter(p -> p.equals(artifact.getGeneratedFromId())).findAny();
+	                            if (op.isPresent()) {
+	                                artifactsUid.add(artifact.getArtifactUUID());
+	                                artifactsId.add(artifact.getUniqueId());
+	
+	                            }
+	                        }
+                        }
+                        groupInstance.setGroupInstanceArtifacts(artifactsId);
+                        groupInstance.setGroupInstanceArtifactsUuid(artifactsUid);
+                        groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
+                    }
+                    if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
+                        instGroups.put(vfInst.getUniqueId(), new MapGroupsDataDefinition(groupInstanceToCreate));
 
-							}
-						}
-						groupInstance.setGroupInstanceArtifacts(artifactsId);
-						groupInstance.setGroupInstanceArtifactsUuid(artifactsUid);
-						groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
-					}
-					if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
-						instGroups.put(vfInst.getUniqueId(), new MapGroupsDataDefinition(groupInstanceToCreate));
+                    }
+                }
+            }
+        }
+    }
 
-					}
-				}
-			}
-		}
-	}
+    private GraphVertex cloneGraphVertexForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
+        GraphVertex nextVersionToscaElementVertex = new GraphVertex();
+        String uniqueId = UniqueIdBuilder.buildComponentUniqueId();
+        Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
+        nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
+        nextVersionToscaElementVertex.setUniqueId(uniqueId);
+        nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
+        nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
 
-	private GraphVertex cloneGraphVertexForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
-		GraphVertex nextVersionToscaElementVertex = new GraphVertex();
-		String uniqueId = UniqueIdBuilder.buildComponentUniqueId();
-		Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
-		nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
-		nextVersionToscaElementVertex.setUniqueId(uniqueId);
-		nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
-		nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
+        nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
+        nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
+        String nextVersion = getNextVersion((String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION));
+        if (isFirstCheckoutAfterCertification(nextVersion)) {
+            nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UUID, IdBuilderUtils.generateUUID());
+        }
+        nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, nextVersion);
+        nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
+        nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
 
-		nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
-		nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
-		String nextVersion = getNextVersion((String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION));
-		if (isFirstCheckoutAfterCertification(nextVersion)) {
-			nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UUID, IdBuilderUtils.generateUUID());
-		}
-		nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, nextVersion);
-		nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
-		nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
+            nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name());
+        }
+        if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
+            nextVersionToscaElementVertex.setMetadataJson(new HashMap<>(toscaElementVertex.getMetadataJson()));
+            nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
+        }
+        long currTime = System.currentTimeMillis();
+        nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, currTime);
+        nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currTime);
+        nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
+        nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
+        if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
+            nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CONFORMANCE_LEVEL, ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
+        }
 
-		if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
-			nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.getValue());
-		}
-		if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
-			nextVersionToscaElementVertex.setMetadataJson(new HashMap<String, Object>(toscaElementVertex.getMetadataJson()));
-			nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
-		}
-		long currTime = System.currentTimeMillis();
-		nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, currTime);
-		nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currTime);
-		nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
-		nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
-		if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
-			nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CONFORMANCE_LEVEL, ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
-		}
+        if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
+            nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
+        }
+        return nextVersionToscaElementVertex;
+    }
 
-		if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
-			nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
-		}
-		return nextVersionToscaElementVertex;
-	}
+    private Either<GraphVertex, StorageOperationStatus> cloneToscaElementForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
+        Either<GraphVertex, StorageOperationStatus> result;
+        Either<List<GraphVertex>, StorageOperationStatus> deleteResult = null;
+        GraphVertex clonedToscaElement = null;
+        result = getToscaElementOperation(toscaElementVertex.getLabel()).cloneToscaElement(toscaElementVertex, cloneGraphVertexForCertify(toscaElementVertex, modifierVertex, majorVersion), modifierVertex);
+        if (result.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element {} for certification. Sattus is {}. ", toscaElementVertex.getUniqueId(), result.right().value());
+        } else {
+            clonedToscaElement = result.left().value();
+            StorageOperationStatus updateEdgeToCatalog = updateEdgeToCatalogRoot(clonedToscaElement, toscaElementVertex);
+            if (updateEdgeToCatalog != StorageOperationStatus.OK) {
+                return Either.right(updateEdgeToCatalog);
+            }
+            deleteResult = deleteAllPreviousNotCertifiedVersions(toscaElementVertex);
+            if (deleteResult.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete all previous npt certified versions of tosca element {}. Status is {}. ", toscaElementVertex.getUniqueId(), deleteResult.right().value());
+                result = Either.right(deleteResult.right().value());
+            }
+        }
+        if (result.isLeft()) {
+            result = handlePreviousVersionRelation(clonedToscaElement, deleteResult.left().value(), majorVersion);
+        }
+        return result;
+    }
 
-	private Either<GraphVertex, StorageOperationStatus> cloneToscaElementForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
-		Either<GraphVertex, StorageOperationStatus> result;
-		Either<List<GraphVertex>, StorageOperationStatus> deleteResult = null;
-		GraphVertex clonedToscaElement = null;
-		result = getToscaElementOperation(toscaElementVertex.getLabel()).cloneToscaElement(toscaElementVertex, cloneGraphVertexForCertify(toscaElementVertex, modifierVertex, majorVersion), modifierVertex);
-		if (result.isRight()) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to clone tosca element {} for certification. Sattus is {}. ", toscaElementVertex.getUniqueId(), result.right().value());
-		} else {
-			clonedToscaElement = result.left().value();
-			StorageOperationStatus updateEdgeToCatalog = updateEdgeToCatalogRoot(clonedToscaElement, toscaElementVertex);
-			if (updateEdgeToCatalog != StorageOperationStatus.OK) {
-				return Either.right(updateEdgeToCatalog);
-			}
-			deleteResult = deleteAllPreviousNotCertifiedVersions(toscaElementVertex);
-			if (deleteResult.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete all previous npt certified versions of tosca element {}. Status is {}. ", toscaElementVertex.getUniqueId(), deleteResult.right().value());
-				result = Either.right(deleteResult.right().value());
-			}
-		}
-		if (result.isLeft()) {
-			result = handlePreviousVersionRelation(clonedToscaElement, deleteResult.left().value(), majorVersion);
-		}
-		return result;
-	}
+    private Either<GraphVertex, StorageOperationStatus> handlePreviousVersionRelation(GraphVertex clonedToscaElement, List<GraphVertex> deletedVersions, Integer majorVersion) {
+        Either<GraphVertex, StorageOperationStatus> result = null;
+        Vertex previousCertifiedToscaElement = null;
+        if (majorVersion > 0) {
+            List<GraphVertex> firstMinorVersionVertex = deletedVersions.stream().filter(gv -> getMinorVersion((String) gv.getMetadataProperty(GraphPropertyEnum.VERSION)) == 1).collect(Collectors.toList());
 
-	private Either<GraphVertex, StorageOperationStatus> handlePreviousVersionRelation(GraphVertex clonedToscaElement, List<GraphVertex> deletedVersions, Integer majorVersion) {
-		Either<GraphVertex, StorageOperationStatus> result = null;
-		Vertex previousCertifiedToscaElement = null;
-		if (majorVersion > 0) {
-			List<GraphVertex> firstMinorVersionVertex = deletedVersions.stream().filter(gv -> getMinorVersion((String) gv.getMetadataProperty(GraphPropertyEnum.VERSION)) == 1).collect(Collectors.toList());
+            if (CollectionUtils.isEmpty(firstMinorVersionVertex)) {
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+            } else {
+                previousCertifiedToscaElement = getPreviousCertifiedToscaElement(firstMinorVersionVertex.get(0));
+                if (previousCertifiedToscaElement == null) {
+                    result = Either.right(StorageOperationStatus.NOT_FOUND);
+                }
+            }
+            if (result == null) {
+                TitanOperationStatus status = titanDao.createEdge(previousCertifiedToscaElement, clonedToscaElement.getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
+                if (status != TitanOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
+                            previousCertifiedToscaElement.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), clonedToscaElement.getUniqueId(), status);
+                    result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+                }
+            }
 
-			if (CollectionUtils.isEmpty(firstMinorVersionVertex)) {
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-			} else {
-				previousCertifiedToscaElement = getPreviousCertifiedToscaElement(firstMinorVersionVertex.get(0));
-				if (previousCertifiedToscaElement == null) {
-					result = Either.right(StorageOperationStatus.NOT_FOUND);
-				}
-			}
-			if (result == null) {
-				TitanOperationStatus status = titanDao.createEdge(previousCertifiedToscaElement, clonedToscaElement.getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
-				if (status != TitanOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
-							previousCertifiedToscaElement.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), clonedToscaElement.getUniqueId(), status);
-					result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-				}
-			}
+        }
+        if (result == null) {
+            result = Either.left(clonedToscaElement);
+        }
+        return result;
+    }
 
-		}
-		if (result == null) {
-			result = Either.left(clonedToscaElement);
-		}
-		return result;
-	}
+    private Vertex getPreviousCertifiedToscaElement(GraphVertex graphVertex) {
 
-	private Vertex getPreviousCertifiedToscaElement(GraphVertex graphVertex) {
+        Iterator<Edge> edges = graphVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
+        if (edges.hasNext()) {
+            return edges.next().outVertex();
+        }
+        return null;
+    }
 
-		Iterator<Edge> edges = graphVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
-		if (edges.hasNext()) {
-			return edges.next().outVertex();
-		}
-		return null;
-	}
+    private Either<List<GraphVertex>, StorageOperationStatus> deleteAllPreviousNotCertifiedVersions(GraphVertex toscaElementVertex) {
+        Either<List<GraphVertex>, StorageOperationStatus> result = null;
 
-	private Either<List<GraphVertex>, StorageOperationStatus> deleteAllPreviousNotCertifiedVersions(GraphVertex toscaElementVertex) {
-		Either<List<GraphVertex>, StorageOperationStatus> result = null;
+        ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
+        List<GraphVertex> previosVersions = null;
+        Object uuid = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.UUID);
+        Object componentName = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NAME);
+        try {
+            Map<GraphPropertyEnum, Object> properties = new HashMap<>();
+            properties.put(GraphPropertyEnum.UUID, uuid);
+            properties.put(GraphPropertyEnum.NAME, componentName);
+            Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes = titanDao.getByCriteria(toscaElementVertex.getLabel(), properties, JsonParseFlagEnum.ParseMetadata);
+            if (getToscaElementsRes.isRight()) {
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
+            }
+            if (result == null) {
+                previosVersions = getToscaElementsRes.left().value();
+                Either<Boolean, StorageOperationStatus> deleteResult = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
+                if (deleteResult.isRight()) {
+                    result = Either.right(deleteResult.right().value());
+                }
+            }
+            if (result == null) {
+                result = Either.left(previosVersions);
+            }
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
+        }
+        return result;
+    }
 
-		ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
-		List<GraphVertex> previosVersions = null;
-		Object uuid = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.UUID);
-		Object componentName = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NAME);
-		try {
-			Map<GraphPropertyEnum, Object> properties = new HashMap<>();
-			properties.put(GraphPropertyEnum.UUID, uuid);
-			properties.put(GraphPropertyEnum.NAME, componentName);
-			Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes = titanDao.getByCriteria(toscaElementVertex.getLabel(), properties, JsonParseFlagEnum.ParseMetadata);
-			if (getToscaElementsRes.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
-			}
-			if (result == null) {
-				previosVersions = getToscaElementsRes.left().value();
-				Either<Boolean, StorageOperationStatus> deleteResult = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
-				if (deleteResult.isRight()) {
-					result = Either.right(deleteResult.right().value());
-				}
-			}
-			if (result == null) {
-				result = Either.left(previosVersions);
-			}
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
-		}
-		return result;
-	}
+    private GraphVertex cloneGraphVertexForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
 
-	private GraphVertex cloneGraphVertexForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
+        GraphVertex nextVersionToscaElementVertex = new GraphVertex();
+        String uniqueId = IdBuilderUtils.generateUniqueId();
+        Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
+        nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
+        nextVersionToscaElementVertex.setUniqueId(uniqueId);
+        nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
+        nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
 
-		GraphVertex nextVersionToscaElementVertex = new GraphVertex();
-		String uniqueId = IdBuilderUtils.generateUniqueId();
-		Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
-		nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
-		nextVersionToscaElementVertex.setUniqueId(uniqueId);
-		nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
-		nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
+        nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
+        nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
+        nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, (majorVersion + 1) + VERSION_DELIMITER + "0");
+        nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
+        nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, System.currentTimeMillis());
+        nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, null);
+        nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
+        nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
 
-		nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
-		nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
-		nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, (majorVersion + 1) + VERSION_DELIMETER + "0");
-		nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
-		nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
-		nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, System.currentTimeMillis());
-		nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, null);
-		nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
-		nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
+        if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED)) {
+            nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name());
+        }
+        if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
+            nextVersionToscaElementVertex.setMetadataJson(new HashMap<>(toscaElementVertex.getMetadataJson()));
+            nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
+        }
+        if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
+            nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
+        }
+        return nextVersionToscaElementVertex;
+    }
 
-		if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED)) {
-			nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.getValue());
-		}
-		if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
-			nextVersionToscaElementVertex.setMetadataJson(new HashMap<String, Object>(toscaElementVertex.getMetadataJson()));
-			nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
-		}
-		if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
-			nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
-		}
-		return nextVersionToscaElementVertex;
-	}
+    private ComponentParametersView buildComponentParametersViewAfterCheckin() {
+        ComponentParametersView componentParametersView = new ComponentParametersView();
+        componentParametersView.disableAll();
+        componentParametersView.setIgnoreUsers(false);
+        return componentParametersView;
+    }
 
-	private ComponentParametersView buildComponentParametersViewAfterCheckin() {
-		ComponentParametersView componentParametersView = new ComponentParametersView();
-		componentParametersView.disableAll();
-		componentParametersView.setIgnoreUsers(false);
-		return componentParametersView;
-	}
+    private Either<GraphVertex, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex, LifecycleStateEnum nextState) {
+        Either<GraphVertex, StorageOperationStatus> updateRelationsRes;
+        Either<GraphVertex, StorageOperationStatus> result = changeStateToCheckedIn(currState, toscaElementVertex, ownerVertex, modifierVertex);
+        if (result.isLeft()) {
+            toscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
+            toscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
+            result = updateToscaElementVertexMetadataPropertiesAndJson(toscaElementVertex);
+        }
+        if (result.isLeft()) {
+            updateRelationsRes = updateLastModifierEdge(toscaElementVertex, ownerVertex, modifierVertex);
+            if (updateRelationsRes.isRight()) {
+                result = Either.right(updateRelationsRes.right().value());
+            }
+        }
+        return result;
+    }
 
-	private Either<GraphVertex, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex, LifecycleStateEnum nextState) {
-		Either<GraphVertex, StorageOperationStatus> updateRelationsRes;
-		Either<GraphVertex, StorageOperationStatus> result = changeStateToCheckedIn(currState, toscaElementVertex, ownerVertex, modifierVertex);
-		if (result.isLeft()) {
-			toscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
-			toscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
-			result = updateToscaElementVertexMetadataPropertiesAndJson(toscaElementVertex);
-		}
-		if (result.isLeft()) {
-			updateRelationsRes = updateLastModifierEdge(toscaElementVertex, ownerVertex, modifierVertex);
-			if (updateRelationsRes.isRight()) {
-				result = Either.right(updateRelationsRes.right().value());
-			}
-		}
-		return result;
-	}
+    private Either<GraphVertex, StorageOperationStatus> updateToscaElementVertexMetadataPropertiesAndJson(GraphVertex toscaElementVertex) {
 
-	private Either<GraphVertex, StorageOperationStatus> updateToscaElementVertexMetadataPropertiesAndJson(GraphVertex toscaElementVertex) {
+        Either<GraphVertex, StorageOperationStatus> result;
 
-		Either<GraphVertex, StorageOperationStatus> result;
+        Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
+        if (updateVertexRes.isRight()) {
+            TitanOperationStatus titatStatus = updateVertexRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update state of tosca element vertex {} metadata. Status is  {}", toscaElementVertex.getUniqueId(), titatStatus);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus));
+        } else {
+            result = Either.left(updateVertexRes.left().value());
+        }
+        return result;
+    }
 
-		Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
-		if (updateVertexRes.isRight()) {
-			TitanOperationStatus titatStatus = updateVertexRes.right().value();
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update state of tosca element vertex {} metadata. Status is  {}", toscaElementVertex.getUniqueId(), titatStatus);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus));
-		} else {
-			result = Either.left(updateVertexRes.left().value());
-		}
-		return result;
-	}
+    private Either<GraphVertex, StorageOperationStatus> changeStateToCheckedIn(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
+        Either<GraphVertex, StorageOperationStatus> result = null;
+        LifecycleStateEnum nextState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN;
+        String faileToUpdateStateMsg = "Failed to update state of tosca element {}. Status is  {}";
 
-	private Either<GraphVertex, StorageOperationStatus> changeStateToCheckedIn(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
-		Either<GraphVertex, StorageOperationStatus> result = null;
-		LifecycleStateEnum nextState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN;
-		String faileToUpdateStateMsg = "Failed to update state of tosca element {}. Status is  {}";
+        if (currState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
+            // In case of cancel "ready for certification" remove last state edge with "STATE" property equals to "NOT_CERTIFIED_CHECKIN"
+            Map<GraphPropertyEnum, Object> vertexProperties = new HashMap<>();
+            vertexProperties.put(GraphPropertyEnum.STATE, nextState);
+            Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElementVertex, EdgeLabelEnum.LAST_STATE, vertexProperties);
+            if (deleteResult.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId(), deleteResult.right().value());
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "failed to update last state relation");
+                result = Either.right(StorageOperationStatus.INCONSISTENCY);
+            }
+        }
+        if (result == null) {
+            // Remove CHECKOUT relation
+            Either<Edge, TitanOperationStatus> deleteEdgeResult = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
+            if (deleteEdgeResult.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeResult.right().value()));
+            }
+        }
+        if (result == null) {
+            // Create CHECKIN relation
+            Map<EdgePropertyEnum, Object> edgeProperties = new HashMap<>();
+            edgeProperties.put(EdgePropertyEnum.STATE, nextState);
+            TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.STATE, edgeProperties);
+            if (createEdgeRes != TitanOperationStatus.OK) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
+            }
+        }
+        if (result == null) {
+            result = Either.left(toscaElementVertex);
+        }
+        return result;
+    }
 
-		if (currState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
-			// In case of cancel "ready for certification" remove last state edge with "STATE" property equals to "NOT_CERTIFIED_CHECKIN"
-			Map<GraphPropertyEnum, Object> vertexProperties = new HashMap<>();
-			vertexProperties.put(GraphPropertyEnum.STATE, nextState);
-			Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElementVertex, EdgeLabelEnum.LAST_STATE, vertexProperties);
-			if (deleteResult.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId(), deleteResult.right().value());
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "failed to update last state relation");
-				result = Either.right(StorageOperationStatus.INCONSISTENCY);
-			}
-		}
-		if (result == null) {
-			// Remove CHECKOUT relation
-			Either<Edge, TitanOperationStatus> deleteEdgeResult = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
-			if (deleteEdgeResult.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeResult.right().value()));
-			}
-		}
-		if (result == null) {
-			// Create CHECKIN relation
-			Map<EdgePropertyEnum, Object> edgeProperties = new HashMap<>();
-			edgeProperties.put(EdgePropertyEnum.STATE, nextState);
-			TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.STATE, edgeProperties);
-			if (createEdgeRes != TitanOperationStatus.OK) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
-			}
-		}
-		if (result == null) {
-			result = Either.left(toscaElementVertex);
-		}
-		return result;
-	}
+    private Either<GraphVertex, StorageOperationStatus> updateLastModifierEdge(GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
+        Either<GraphVertex, StorageOperationStatus> result = null;
+        if (!modifierVertex.getMetadataProperties().get(GraphPropertyEnum.USERID).equals(ownerVertex.getMetadataProperties().get(GraphPropertyEnum.USERID))) {
+            Either<Edge, TitanOperationStatus> deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.LAST_MODIFIER);
+            if (deleteEdgeRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete last modifier {} to tosca element {}. Edge type is {}", ownerVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeRes.right().value()));
+            }
+            if (result == null) {
+                TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
 
-	private Either<GraphVertex, StorageOperationStatus> updateLastModifierEdge(GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
-		Either<GraphVertex, StorageOperationStatus> result = null;
-		if (!modifierVertex.getMetadataProperties().get(GraphPropertyEnum.USERID).equals(ownerVertex.getMetadataProperties().get(GraphPropertyEnum.USERID))) {
-			Either<Edge, TitanOperationStatus> deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.LAST_MODIFIER);
-			if (deleteEdgeRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last modifier {} to tosca element {}. Edge type is {}", ownerVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeRes.right().value()));
-			}
-			if (result == null) {
-				TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
+                if (createEdgeRes != TitanOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to associate user {} to component {}. Edge type is {}", modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
+                    result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
+                } else {
+                    result = Either.left(modifierVertex);
+                }
+            }
+        } else {
+            result = Either.left(ownerVertex);
+        }
+        return result;
+    }
 
-				if (createEdgeRes != TitanOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to associate user {} to component {}. Edge type is {}", modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
-					result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
-				} else {
-					result = Either.left(modifierVertex);
-				}
-			}
-		} else {
-			result = Either.left(ownerVertex);
-		}
-		return result;
-	}
+    private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckin(String toscaElementId, String modifierId, String ownerId) {
+        Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
+        verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseMetadata));
+        verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
+        verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
+        return verticesToGetParameters;
+    }
 
-	private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckin(String toscaElementId, String modifierId, String ownerId) {
-		Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
-		verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseMetadata));
-		verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
-		verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
-		return verticesToGetParameters;
-	}
+    private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForRequestCertification(String toscaElementId, String modifierId, String ownerId) {
+        Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
+        verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
+        verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
+        verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
+        return verticesToGetParameters;
+    }
 
-	private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForRequestCertification(String toscaElementId, String modifierId, String ownerId) {
-		Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
-		verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
-		verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
-		verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
-		return verticesToGetParameters;
-	}
+    private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckout(String toscaElementId, String modifierId, String ownerId) {
+    	//Implementation is currently identical
+    	return prepareParametersToGetVerticesForRequestCertification(toscaElementId,modifierId, ownerId);
+    }
 
-	private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckout(String toscaElementId, String modifierId, String ownerId) {
-		Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
-		verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
-		verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
-		verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
-		return verticesToGetParameters;
-	}
+    private String getNextCertifiedVersion(String version) {
+        String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
+        Integer nextMajorVersion = Integer.parseInt(versionParts[0]) + 1;
+        return nextMajorVersion + VERSION_DELIMITER + "0";
+    }
 
-	private String getNextCertifiedVersion(String version) {
-		String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
-		Integer nextMajorVersion = Integer.parseInt(versionParts[0]) + 1;
-		return nextMajorVersion + VERSION_DELIMETER + "0";
-	}
+    private String getNextVersion(String currVersion) {
+        String[] versionParts = currVersion.split(VERSION_DELIMITER_REGEXP);
+        Integer minorVersion = Integer.parseInt(versionParts[1]) + 1;
+        return versionParts[0] + VERSION_DELIMITER + minorVersion;
+    }
 
-	private String getNextVersion(String currVersion) {
-		String[] versionParts = currVersion.split(VERSION_DELIMETER_REGEXP);
-		Integer minorVersion = Integer.parseInt(versionParts[1]) + 1;
-		return versionParts[0] + VERSION_DELIMETER + minorVersion;
-	}
+    private Integer getMinorVersion(String version) {
+        String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
+        return Integer.parseInt(versionParts[1]);
+    }
 
-	private Integer getMinorVersion(String version) {
-		String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
-		return Integer.parseInt(versionParts[1]);
-	}
+    private Integer getMajorVersion(String version) {
+        String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
+        return Integer.parseInt(versionParts[0]);
+    }
 
-	private Integer getMajorVersion(String version) {
-		String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
-		return Integer.parseInt(versionParts[0]);
-	}
+    private boolean isFirstCheckoutAfterCertification(String version) {
+        return (Integer.parseInt(version.split(VERSION_DELIMITER_REGEXP)[0]) != 0 && Integer.parseInt(version.split(VERSION_DELIMITER_REGEXP)[1]) == 1);
+    }
 
-	private boolean isFirstCheckoutAfterCertification(String version) {
-		if (Integer.parseInt(version.split(VERSION_DELIMETER_REGEXP)[0]) != 0 && Integer.parseInt(version.split(VERSION_DELIMETER_REGEXP)[1]) == 1) {
-			return true;
-		}
-		return false;
-	}
+    public Either<ToscaElement, StorageOperationStatus> forceCerificationOfToscaElement(String toscaElementId, String modifierId, String ownerId, String currVersion) {
+        Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
+        Either<ToscaElement, StorageOperationStatus> result = null;
+        GraphVertex toscaElement = null;
+        GraphVertex modifier = null;
+        GraphVertex owner;
+        try {
+            Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
+            if (getVerticesRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
+            }
+            if (result == null) {
+                toscaElement = getVerticesRes.left().value().get(toscaElementId);
+                modifier = getVerticesRes.left().value().get(modifierId);
+                owner = getVerticesRes.left().value().get(ownerId);
 
-	public Either<ToscaElement, StorageOperationStatus> forceCerificationOfToscaElement(String toscaElementId, String modifierId, String ownerId, String currVersion) {
-		Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
-		Either<ToscaElement, StorageOperationStatus> result = null;
-		GraphVertex toscaElement = null;
-		GraphVertex modifier = null;
-		GraphVertex owner;
-		try {
-			Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
-			if (getVerticesRes.isRight()) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
-			}
-			if (result == null) {
-				toscaElement = getVerticesRes.left().value().get(toscaElementId);
-				modifier = getVerticesRes.left().value().get(modifierId);
-				owner = getVerticesRes.left().value().get(ownerId);
+                StorageOperationStatus status = handleRelationsUponForceCertification(toscaElement, modifier, owner);
+                if (status != StorageOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
+                }
+            }
+            if (result == null) {
+                LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFIED;
 
-				StorageOperationStatus status = handleRelationsUponForceCertification(toscaElement, modifier, owner);
-				if (status != StorageOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
-				}
-			}
-			if (result == null) {
-				LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFIED;
+                toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
+                toscaElement.addMetadataProperty(GraphPropertyEnum.VERSION, getNextCertifiedVersion(currVersion));
 
-				toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
-				toscaElement.addMetadataProperty(GraphPropertyEnum.VERSION, getNextCertifiedVersion(currVersion));
+                resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
+                if (resultUpdate.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
+                    result = Either.right(resultUpdate.right().value());
+                }
+            }
+            if (result == null) {
+                ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
+                result = operation.getToscaElement(toscaElement.getUniqueId());
+            }
+            return result;
 
-				resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
-				if (resultUpdate.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
-					result = Either.right(resultUpdate.right().value());
-				}
-			}
-			if (result == null) {
-				ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
-				result = operation.getToscaElement(toscaElement.getUniqueId());
-			}
-			return result;
+        } catch (Exception e) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
+        }
+        return result;
+    }
 
-		} catch (Exception e) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
-		}
-		return result;
-	}
+    private StorageOperationStatus handleRelationsUponForceCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
 
-	private StorageOperationStatus handleRelationsUponForceCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
+        StorageOperationStatus result = null;
+        TitanOperationStatus status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
+        if (status != TitanOperationStatus.OK) {
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (result == null) {
+            Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
+            properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFIED);
+            status = titanDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
+            if (status != TitanOperationStatus.OK) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
+                result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+            }
+        }
+        if (result == null) {
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
 
-		StorageOperationStatus result = null;
-		TitanOperationStatus status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
-		if (status != TitanOperationStatus.OK) {
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (result == null) {
-			Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
-			properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFIED);
-			status = titanDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
-			if (status != TitanOperationStatus.OK) {
-				CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-			}
-		}
-		if (result == null) {
-			result = StorageOperationStatus.OK;
-		}
-		return result;
-	}
+    private StorageOperationStatus updateEdgeToCatalogRootByUndoCheckout(TitanVertex preV, GraphVertex curV) {
+        if (preV == null) {
+            return updateEdgeToCatalogRoot(null, curV);
+        }
+        String uniqueIdPreVer = (String) titanDao.getProperty((TitanVertex) preV, GraphPropertyEnum.UNIQUE_ID.getProperty());
+        LifecycleStateEnum state = LifecycleStateEnum.findState((String) titanDao.getProperty(preV, GraphPropertyEnum.STATE.getProperty()));
+        if (state == LifecycleStateEnum.CERTIFIED) {
+            return updateEdgeToCatalogRoot(null, curV);
+        }
+        return titanDao.getVertexById(uniqueIdPreVer)
+                .either(l -> updateEdgeToCatalogRoot(l, curV),
+                        DaoStatusConverter::convertTitanStatusToStorageStatus);
+    }
 
-	private StorageOperationStatus updateEdgeToCatalogRoot(GraphVertex newVersionV, GraphVertex prevVersionV) {
-		Either<GraphVertex, TitanOperationStatus> catalog = titanDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT);
-		if (catalog.isRight()) {
-			CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch catalog vertex. error {}", catalog.right().value());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(catalog.right().value());
-		}
-		GraphVertex catalogV = catalog.left().value();
-		if (newVersionV != null) {
-			Boolean isAbstract = (Boolean) newVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
-			if (isAbstract == null || !isAbstract) {
-				// no new vertex, only delete previous
-				TitanOperationStatus result = titanDao.createEdge(catalogV, newVersionV, EdgeLabelEnum.CATALOG_ELEMENT, null);
-				if (result != TitanOperationStatus.OK) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge from {} to catalog vertex. error {}", newVersionV.getUniqueId(), result);
-					return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
-				}
-			}
-		}
-		if (prevVersionV != null) {
-			Boolean isAbstract = (Boolean) prevVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
-			if (isAbstract == null || !isAbstract) {
-				// if prev == null -> new resource was added
-				Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteEdge(catalogV, prevVersionV, EdgeLabelEnum.CATALOG_ELEMENT);
-				if (deleteResult.isRight()) {
-					CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete edge from {} to catalog vertex. error {}", prevVersionV.getUniqueId(), deleteResult.right().value());
-					return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteResult.right().value());
-				}
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    private StorageOperationStatus updateEdgeToCatalogRoot(GraphVertex newVersionV, GraphVertex prevVersionV) {
+        Either<GraphVertex, TitanOperationStatus> catalog = titanDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT);
+        if (catalog.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch catalog vertex. error {}", catalog.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(catalog.right().value());
+        }
+        GraphVertex catalogV = catalog.left().value();
+        if (newVersionV != null) {
+            Boolean isAbstract = (Boolean) newVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
+			
+			if ( isAbstract == null || !isAbstract ) {
+                // no new vertex, only delete previous
+                TitanOperationStatus result = titanDao.createEdge(catalogV, newVersionV, EdgeLabelEnum.CATALOG_ELEMENT, null);
+                if (result != TitanOperationStatus.OK) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge from {} to catalog vertex. error {}", newVersionV.getUniqueId(), result);
+                    return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
+                }
+            }
+        }
+        if (prevVersionV != null) {
+            Boolean isAbstract = (Boolean) prevVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
+            if (isAbstract == null || !isAbstract) {
+                // if prev == null -> new resource was added
+                Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteEdge(catalogV, prevVersionV, EdgeLabelEnum.CATALOG_ELEMENT);
+                if (deleteResult.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge from {} to catalog vertex. error {}", prevVersionV.getUniqueId(), deleteResult.right().value());
+                    return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteResult.right().value());
+                }
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperation.java
index df7b382..a97f033 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperation.java
@@ -7,9 +7,9 @@
  * 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.
@@ -23,6 +23,7 @@
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 import fj.data.Either;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -58,16 +59,15 @@
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.StopWatch;
 
 import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -75,7 +75,13 @@
 import java.util.Set;
 
 public abstract class ToscaElementOperation extends BaseOperation {
-    private static Logger log = LoggerFactory.getLogger(ToscaElementOperation.class.getName());
+    private static final String FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR = "failed to fetch {} for tosca element with id {}, error {}";
+
+    private static final String CANNOT_FIND_USER_IN_THE_GRAPH_STATUS_IS = "Cannot find user {} in the graph. status is {}";
+
+    private static final String FAILED_TO_CREATE_EDGE_WITH_LABEL_FROM_USER_VERTEX_TO_TOSCA_ELEMENT_VERTEX_ON_GRAPH_STATUS_IS = "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ";
+
+    private static Logger log = Logger.getLogger(ToscaElementOperation.class.getName());
 
     private static final Gson gson = new Gson();
 
@@ -88,7 +94,7 @@
 
     protected Either<GraphVertex, StorageOperationStatus> getComponentByLabelAndId(String uniqueId, ToscaElementTypeEnum nodeType, JsonParseFlagEnum parseFlag) {
 
-        Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
         propertiesToMatch.put(GraphPropertyEnum.UNIQUE_ID, uniqueId);
 
         VertexTypeEnum vertexType = ToscaElementTypeEnum.getVertexTypeByToscaType(nodeType);
@@ -141,7 +147,7 @@
 
     /**
      * Performs a shadow clone of previousToscaElement
-     * 
+     *
      * @param previousToscaElement
      * @param nextToscaElement
      * @param user
@@ -162,11 +168,11 @@
         }
         if (result == null) {
             createdToscaElementVertex = createNextVersionRes.left().value();
-            Map<EdgePropertyEnum, Object> properties = new HashMap<EdgePropertyEnum, Object>();
+            Map<EdgePropertyEnum, Object> properties = new HashMap<>();
             properties.put(EdgePropertyEnum.STATE, createdToscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE));
             status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.STATE, properties);
             if (status != TitanOperationStatus.OK) {
-                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.STATE, user.getUniqueId(),
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_CREATE_EDGE_WITH_LABEL_FROM_USER_VERTEX_TO_TOSCA_ELEMENT_VERTEX_ON_GRAPH_STATUS_IS, EdgeLabelEnum.STATE, user.getUniqueId(),
                         previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
             }
@@ -174,7 +180,7 @@
         if (result == null) {
             status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
             if (status != TitanOperationStatus.OK) {
-                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.LAST_MODIFIER, user.getUniqueId(),
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_CREATE_EDGE_WITH_LABEL_FROM_USER_VERTEX_TO_TOSCA_ELEMENT_VERTEX_ON_GRAPH_STATUS_IS, EdgeLabelEnum.LAST_MODIFIER, user.getUniqueId(),
                         nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
             }
@@ -182,7 +188,7 @@
         if (result == null) {
             status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.CREATOR, new HashMap<>());
             if (status != TitanOperationStatus.OK) {
-                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.CREATOR, user.getUniqueId(),
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_CREATE_EDGE_WITH_LABEL_FROM_USER_VERTEX_TO_TOSCA_ELEMENT_VERTEX_ON_GRAPH_STATUS_IS, EdgeLabelEnum.CREATOR, user.getUniqueId(),
                         nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
             }
@@ -290,6 +296,9 @@
         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.INVARIANT_UUID, toscaElement.getMetadataValue(JsonPresentationFields.INVARIANT_UUID));
         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NAME, toscaElement.getMetadataValue(JsonPresentationFields.NAME));
         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.SYSTEM_NAME, toscaElement.getMetadataValue(JsonPresentationFields.SYSTEM_NAME));
+        nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_ARCHIVED, toscaElement.getMetadataValue(JsonPresentationFields.IS_ARCHIVED));
+        nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.ARCHIVE_TIME, toscaElement.getMetadataValue(JsonPresentationFields.ARCHIVE_TIME));
+        nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_VSP_ARCHIVED, toscaElement.getMetadataValue(JsonPresentationFields.IS_VSP_ARCHIVED));
         toscaElement.getMetadata().entrySet().stream().filter(e -> e.getValue() != null).forEach(e -> nodeTypeVertex.setJsonMetadataField(JsonPresentationFields.getByPresentation(e.getKey()), e.getValue()));
 
         nodeTypeVertex.setUniqueId(toscaElement.getUniqueId());
@@ -305,7 +314,7 @@
 
         if (findUser.isRight()) {
             TitanOperationStatus status = findUser.right().value();
-            log.error("Cannot find user {} in the graph. status is {}", userId, status);
+            log.error(CANNOT_FIND_USER_IN_THE_GRAPH_STATUS_IS, userId, status);
             return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
 
         }
@@ -316,13 +325,13 @@
             findUser = findUserVertex(updaterId);
             if (findUser.isRight()) {
                 TitanOperationStatus status = findUser.right().value();
-                log.error("Cannot find user {} in the graph. status is {}", userId, status);
+                log.error(CANNOT_FIND_USER_IN_THE_GRAPH_STATUS_IS, userId, status);
                 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
             } else {
                 updaterVertex = findUser.left().value();
             }
         }
-        Map<EdgePropertyEnum, Object> props = new HashMap<EdgePropertyEnum, Object>();
+        Map<EdgePropertyEnum, Object> props = new HashMap<>();
         props.put(EdgePropertyEnum.STATE, (String) toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
 
         TitanOperationStatus result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.STATE, props);
@@ -397,7 +406,7 @@
                 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
                 a.setUniqueId(uniqueId);
             });
-            status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ARTIFACTS, EdgeLabelEnum.ARTIFACTS, artifacts);
+            status = associateElementToData(nodeTypeVertex, VertexTypeEnum.ARTIFACTS, EdgeLabelEnum.ARTIFACTS, artifacts);
             if (status.isRight()) {
                 return status.right().value();
             }
@@ -408,7 +417,7 @@
                 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
                 a.setUniqueId(uniqueId);
             });
-            status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.TOSCA_ARTIFACTS, EdgeLabelEnum.TOSCA_ARTIFACTS, toscaArtifacts);
+            status = associateElementToData(nodeTypeVertex, VertexTypeEnum.TOSCA_ARTIFACTS, EdgeLabelEnum.TOSCA_ARTIFACTS, toscaArtifacts);
             if (status.isRight()) {
                 return status.right().value();
             }
@@ -419,7 +428,7 @@
                 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
                 a.setUniqueId(uniqueId);
             });
-            status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS, deploymentArtifacts);
+            status = associateElementToData(nodeTypeVertex, VertexTypeEnum.DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS, deploymentArtifacts);
             if (status.isRight()) {
                 return status.right().value();
             }
@@ -546,7 +555,7 @@
             }
         }
         if (!propertiesAll.isEmpty()) {
-            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.PROPERTIES, EdgeLabelEnum.PROPERTIES, propertiesAll);
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.PROPERTIES, EdgeLabelEnum.PROPERTIES, propertiesAll);
             if (assosiateElementToData.isRight()) {
                 return assosiateElementToData.right().value();
             }
@@ -557,7 +566,7 @@
     private StorageOperationStatus associateAdditionalInfoToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
         Map<String, AdditionalInfoParameterDataDefinition> additionalInformation = nodeType.getAdditionalInformation();
         if (additionalInformation != null) {
-            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, additionalInformation);
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, additionalInformation);
             if (assosiateElementToData.isRight()) {
                 return assosiateElementToData.right().value();
             }
@@ -624,7 +633,7 @@
         Map<String, String> allVersion = new HashMap<>();
 
         allVersion.put((String) componentV.getMetadataProperty(GraphPropertyEnum.VERSION), componentV.getUniqueId());
-        ArrayList<GraphVertex> allChildrenAndParants = new ArrayList<GraphVertex>();
+        ArrayList<GraphVertex> allChildrenAndParants = new ArrayList<>();
         Either<GraphVertex, TitanOperationStatus> childResourceRes = titanDao.getChildVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
         while (childResourceRes.isLeft()) {
             GraphVertex child = childResourceRes.left().value();
@@ -648,7 +657,7 @@
             } else {
                 allChildrenAndParants.stream().filter(vertex -> {
                     Boolean isDeleted = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
-                    return (isDeleted == null || isDeleted == false);
+                    return (isDeleted == null || !isDeleted);
                 }).forEach(vertex -> allVersion.put((String) vertex.getMetadataProperty(GraphPropertyEnum.VERSION), vertex.getUniqueId()));
 
                 toscaElement.setAllVersions(allVersion);
@@ -681,7 +690,7 @@
         List<T> componentsPerUser;
         for (GraphVertex userV : users) {
 
-            HashSet<String> ids = new HashSet<String>();
+            HashSet<String> ids = new HashSet<>();
             Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.STATE, JsonParseFlagEnum.NoParse);
             if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
                 log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.STATE, childrenVertecies.right().value());
@@ -716,7 +725,7 @@
                             if (ids.contains(comp.getUniqueId())) {
                                 isFirst = false;
                             }
-                            if (isFirst == true) {
+                            if (isFirst) {
                                 components.add(comp);
                             }
 
@@ -749,8 +758,9 @@
                 if (lifecycleStates != null && lifecycleStates.contains(nodeState)) {
 
                     Boolean isDeleted = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
-                    if (isDeleted != null && isDeleted) {
-                        log.trace("Deleted element  {}, discard", node.getUniqueId());
+                    Boolean isArchived = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_ARCHIVED);
+                    if (isDeleted != null && isDeleted || isArchived != null && isArchived) {
+                        log.trace("Deleted/Archived element  {}, discard", node.getUniqueId());
                         continue;
                     }
 
@@ -766,19 +776,19 @@
                         }
                         if (neededType == componentType) {
                             switch (componentType) {
-                            case SERVICE:
-                            case PRODUCT:
-                                handleNode(components, node, componentType);
-                                break;
-                            case RESOURCE:
-                                Boolean isAbtract = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
-                                if (isAbtract == null || false == isAbtract) {
+                                case SERVICE:
+                                case PRODUCT:
                                     handleNode(components, node, componentType);
-                                } // if not abstract
-                                break;
-                            default:
-                                log.debug("not supported node type {}", componentType);
-                                break;
+                                    break;
+                                case RESOURCE:
+                                    Boolean isAbtract = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
+                                    if (isAbtract == null || !isAbtract) {
+                                        handleNode(components, node, componentType);
+                                    } // if not abstract
+                                    break;
+                                default:
+                                    log.debug("not supported node type {}", componentType);
+                                    break;
                             }// case
                         } // needed type
                     }
@@ -854,15 +864,15 @@
         ToscaElement toscaElement = null;
         VertexTypeEnum label = componentV.getLabel();
         switch (label) {
-        case NODE_TYPE:
-            toscaElement = new NodeType();
-            break;
-        case TOPOLOGY_TEMPLATE:
-            toscaElement = new TopologyTemplate();
-            break;
-        default:
-            log.debug("Not supported tosca type {}", label);
-            break;
+            case NODE_TYPE:
+                toscaElement = new NodeType();
+                break;
+            case TOPOLOGY_TEMPLATE:
+                toscaElement = new TopologyTemplate();
+                break;
+            default:
+                log.debug("Not supported tosca type {}", label);
+                break;
         }
 
         Map<String, Object> jsonMetada = componentV.getMetadataJson();
@@ -872,23 +882,11 @@
         return (T) toscaElement;
     }
 
-    protected TitanOperationStatus setServiceCategoryFromGraphV(Vertex vertex, CatalogComponent catalogComponent) {
-        Either<Vertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(vertex, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
-        if (childVertex.isRight()) {
-            log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, catalogComponent.getUniqueId(), childVertex.right().value());
-            return childVertex.right().value();
-        }
-        Vertex categoryV = childVertex.left().value();
-        catalogComponent.setCategoryNormalizedName((String) categoryV.property(JsonPresentationFields.NORMALIZED_NAME.getPresentation()).value());
-
-        return TitanOperationStatus.OK;
-    }
-
     protected TitanOperationStatus setResourceCategoryFromGraphV(Vertex vertex, CatalogComponent catalogComponent) {
 
         Either<Vertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(vertex, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
         if (childVertex.isRight()) {
-            log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, catalogComponent.getUniqueId(), childVertex.right().value());
+            log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, EdgeLabelEnum.CATEGORY, catalogComponent.getUniqueId(), childVertex.right().value());
             return childVertex.right().value();
         }
         Vertex subCategoryV = childVertex.left().value();
@@ -900,13 +898,25 @@
         return TitanOperationStatus.OK;
     }
 
+    protected TitanOperationStatus setServiceCategoryFromGraphV(Vertex vertex, CatalogComponent catalogComponent) {
+        Either<Vertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(vertex, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
+        if (childVertex.isRight()) {
+            log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, EdgeLabelEnum.CATEGORY, catalogComponent.getUniqueId(), childVertex.right().value());
+            return childVertex.right().value();
+        }
+        Vertex categoryV = childVertex.left().value();
+        catalogComponent.setCategoryNormalizedName((String) categoryV.property(JsonPresentationFields.NORMALIZED_NAME.getPresentation()).value());
+
+        return TitanOperationStatus.OK;
+    }
+
     protected TitanOperationStatus setResourceCategoryFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
         List<CategoryDefinition> categories = new ArrayList<>();
         SubCategoryDefinition subcategory;
 
         Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
         if (childVertex.isRight()) {
-            log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, componentV.getUniqueId(), childVertex.right().value());
+            log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, EdgeLabelEnum.CATEGORY, componentV.getUniqueId(), childVertex.right().value());
             return childVertex.right().value();
         }
         GraphVertex subCategoryV = childVertex.left().value();
@@ -966,12 +976,11 @@
 
         if (findUser.isRight()) {
             TitanOperationStatus status = findUser.right().value();
-            log.error("Cannot find user {} in the graph. status is {}", modifierUserId, status);
+            log.error(CANNOT_FIND_USER_IN_THE_GRAPH_STATUS_IS, modifierUserId, status);
             return result;
         }
 
         GraphVertex modifierV = findUser.left().value();
-        // UserData modifierUserData = findUser.left().value();
         String toscaElementId = toscaElementToUpdate.getUniqueId();
 
         Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(elementV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
@@ -1036,12 +1045,6 @@
                 // TODO call to new Artifact operation in order to update list of artifacts
 
             }
-            // US833308 VLI in service - specific network_role property value logic
-            if (ComponentTypeEnum.SERVICE == toscaElementToUpdate.getComponentType()) {
-                // update method logs success/error and returns boolean (true if nothing fails)
-                // TODO!!!!
-                // updateServiceNameInVLIsNetworkRolePropertyValues(component, prevSystemName, newSystemName);
-            }
         }
 
         if (toscaElementToUpdate.getComponentType() == ComponentTypeEnum.RESOURCE) {
@@ -1086,7 +1089,7 @@
 
         Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(elementV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
         if (childVertex.isRight()) {
-            log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, elementV.getUniqueId(), childVertex.right().value());
+            log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, EdgeLabelEnum.CATEGORY, elementV.getUniqueId(), childVertex.right().value());
             return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
         }
         GraphVertex subCategoryV = childVertex.left().value();
@@ -1107,12 +1110,12 @@
         String newCategoryName = newCategory.getName();
         SubCategoryDefinition newSubcategory = newCategory.getSubcategories().get(0);
         String newSubCategoryName = newSubcategory.getName();
-        if (newCategoryName != null && false == newCategoryName.equals(categoryNameCurrent)) {
+        if (newCategoryName != null && !newCategoryName.equals(categoryNameCurrent)) {
             // the category was changed
             categoryWasChanged = true;
         } else {
             // the sub-category was changed
-            if (newSubCategoryName != null && false == newSubCategoryName.equals(subCategoryNameCurrent)) {
+            if (newSubCategoryName != null && !newSubCategoryName.equals(subCategoryNameCurrent)) {
                 log.debug("Going to update the category of the resource from {} to {}", categoryNameCurrent, newCategory);
                 categoryWasChanged = true;
             }
@@ -1144,7 +1147,7 @@
         List<T> result = new ArrayList<>();
         if (listOfComponents.isLeft()) {
             List<GraphVertex> highestAndAllCertified = listOfComponents.left().value();
-            if (highestAndAllCertified != null && false == highestAndAllCertified.isEmpty()) {
+            if (highestAndAllCertified != null && !highestAndAllCertified.isEmpty()) {
                 for (GraphVertex vertexComponent : highestAndAllCertified) {
                     Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, componentType, new ComponentParametersView(true));
                     if (component.isRight()) {
@@ -1159,29 +1162,42 @@
         return Either.left(result);
     }
 
-    public Either<List<CatalogComponent>, StorageOperationStatus> getElementCatalogData() {
-        List<CatalogComponent> results = new ArrayList<>();
+    public Either<List<CatalogComponent>, StorageOperationStatus> getElementCatalogData(boolean isCatalog, List<ResourceTypeEnum> excludeTypes) {
         StopWatch stopWatch = new StopWatch();
         stopWatch.start();
 
-        Either<Iterator<Vertex>, TitanOperationStatus> verticesEither = titanDao.getCatalogVerticies();
+        Map<String, CatalogComponent> existInCatalog = new HashMap<>();
+        Either<Iterator<Vertex>, TitanOperationStatus> verticesEither = titanDao.getCatalogOrArchiveVerticies(isCatalog);
         if (verticesEither.isRight()) {
             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(verticesEither.right().value()));
         }
         Iterator<Vertex> vertices = verticesEither.left().value();
         while (vertices.hasNext()) {
-            Vertex vertex = vertices.next();
-            VertexProperty<Object> property = vertex.property(GraphPropertiesDictionary.METADATA.getProperty());
-            String json = (String) property.value();
+            handleCatalogComponent(existInCatalog, vertices.next(), excludeTypes);
+        }
+        stopWatch.stop();
+        String timeToFetchElements = stopWatch.prettyPrint();
+        log.info("time to fetch all catalog elements: {}", timeToFetchElements);
+        return Either.left(existInCatalog.values().stream().collect(Collectors.toList()));
+    }
 
+    private void handleCatalogComponent(Map<String, CatalogComponent> existInCatalog, Vertex vertex, List<ResourceTypeEnum> excludeTypes) {
+        VertexProperty<Object> property = vertex.property(GraphPropertiesDictionary.METADATA.getProperty());
+        String json = (String) property.value();
+        Map<String, Object> metadatObj = JsonParserUtils.toMap(json);
+
+        String uniqueId = (String) metadatObj.get(JsonPresentationFields.UNIQUE_ID.getPresentation());
+        Boolean isDeleted = (Boolean) metadatObj.get(JsonPresentationFields.IS_DELETED.getPresentation());
+
+
+        if (isAddToCatalog(excludeTypes, metadatObj) && (existInCatalog.get(uniqueId) == null && (isDeleted == null || !isDeleted.booleanValue()))) {
             CatalogComponent catalogComponent = new CatalogComponent();
-            Map<String, Object> metadatObj = JsonParserUtils.toMap(json);
+            catalogComponent.setUniqueId(uniqueId);
 
             catalogComponent.setComponentType(ComponentTypeEnum.valueOf((String) metadatObj.get(JsonPresentationFields.COMPONENT_TYPE.getPresentation())));
             catalogComponent.setVersion((String) metadatObj.get(JsonPresentationFields.VERSION.getPresentation()));
             catalogComponent.setName((String) metadatObj.get(JsonPresentationFields.NAME.getPresentation()));
             catalogComponent.setIcon((String) metadatObj.get(JsonPresentationFields.ICON.getPresentation()));
-            catalogComponent.setUniqueId((String) metadatObj.get(JsonPresentationFields.UNIQUE_ID.getPresentation()));
             catalogComponent.setLifecycleState((String) metadatObj.get(JsonPresentationFields.LIFECYCLE_STATE.getPresentation()));
             catalogComponent.setLastUpdateDate((Long) metadatObj.get(JsonPresentationFields.LAST_UPDATE_DATE.getPresentation()));
             catalogComponent.setDistributionStatus((String) metadatObj.get(JsonPresentationFields.DISTRIBUTION_STATUS.getPresentation()));
@@ -1196,16 +1212,30 @@
             } else {
                 setResourceCategoryFromGraphV(vertex, catalogComponent);
             }
-            results.add(catalogComponent);
-
+            List<String> tags = (List<String>) metadatObj.get(JsonPresentationFields.TAGS.getPresentation());
+            if (tags != null) {
+                catalogComponent.setTags(tags);
+            }
+            existInCatalog.put(uniqueId, catalogComponent);
         }
-        stopWatch.stop();
-        String timeToFetchElements = stopWatch.prettyPrint();
-        log.info("time to fetch all catalog elements: {}", timeToFetchElements);
-        return Either.left(results);
     }
 
-    public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestComponents(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes, JsonParseFlagEnum parseFlag) {
+    private boolean isAddToCatalog(List<ResourceTypeEnum> excludeTypes, Map<String, Object> metadatObj) {
+        boolean isAddToCatalog = true;
+        Object resourceTypeStr = metadatObj.get(JsonPresentationFields.RESOURCE_TYPE.getPresentation());
+        if (resourceTypeStr != null) {
+            ResourceTypeEnum resourceType = ResourceTypeEnum.getType((String) resourceTypeStr);
+            if (!CollectionUtils.isEmpty(excludeTypes)) {
+                Optional<ResourceTypeEnum> op = excludeTypes.stream().filter(rt -> rt == resourceType).findAny();
+                if (op.isPresent())
+                    isAddToCatalog = false;
+            }
+        }
+        return isAddToCatalog;
+    }
+
+    public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestComponents(ComponentTypeEnum
+                                                                                              componentType, List<ResourceTypeEnum> excludeTypes, JsonParseFlagEnum parseFlag) {
         Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
         Map<GraphPropertyEnum, Object> propertiesHasNotToMatch = new HashMap<>();
         propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
@@ -1216,12 +1246,14 @@
             propertiesHasNotToMatch.put(GraphPropertyEnum.RESOURCE_TYPE, excludeTypes);
         }
         propertiesHasNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+        propertiesHasNotToMatch.put(GraphPropertyEnum.IS_ARCHIVED, true); //US382674, US382683
 
         return titanDao.getByCriteria(null, propertiesToMatch, propertiesHasNotToMatch, parseFlag);
     }
 
     // highest + (certified && !highest)
-    public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestAndAllCertifiedComponents(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes) {
+    public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestAndAllCertifiedComponents
+    (ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes) {
         long startFetchAllStates = System.currentTimeMillis();
         Either<List<GraphVertex>, TitanOperationStatus> highestNodes = getListOfHighestComponents(componentType, excludeTypes, JsonParseFlagEnum.ParseMetadata);
 
@@ -1235,6 +1267,7 @@
         }
 
         propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_DELETED, true);
+        propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_ARCHIVED, true);  //US382674, US382683
         propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
 
         Either<List<GraphVertex>, TitanOperationStatus> certifiedNotHighestNodes = titanDao.getByCriteria(null, propertiesToMatchCertified, propertiesHasNotToMatchCertified, JsonParseFlagEnum.ParseMetadata);
@@ -1257,10 +1290,11 @@
         return Either.left(allNodes);
     }
 
-    protected Either<List<GraphVertex>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
+    protected Either<List<GraphVertex>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum
+                                                                                                          componentType) {
 
         // get all components marked for delete
-        Map<GraphPropertyEnum, Object> props = new HashMap<GraphPropertyEnum, Object>();
+        Map<GraphPropertyEnum, Object> props = new HashMap<>();
         props.put(GraphPropertyEnum.IS_DELETED, true);
         props.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
 
@@ -1279,7 +1313,8 @@
         return Either.left(componentsToDelete.left().value());
     }
 
-    protected TitanOperationStatus setAdditionalInformationFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
+    protected TitanOperationStatus setAdditionalInformationFromGraph(GraphVertex componentV, ToscaElement
+            toscaElement) {
         Either<Map<String, AdditionalInfoParameterDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ADDITIONAL_INFORMATION);
         if (result.isLeft()) {
             toscaElement.setAdditionalInformation(result.left().value());
@@ -1292,24 +1327,34 @@
     }
 
     // --------------------------------------------
-    public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView);
+    public abstract <T extends
+            ToscaElement> Either<T, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView);
 
-    public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(GraphVertex toscaElementVertex, ComponentParametersView componentParametersView);
+    public abstract <T extends
+            ToscaElement> Either<T, StorageOperationStatus> getToscaElement(GraphVertex toscaElementVertex, ComponentParametersView componentParametersView);
 
-    public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex);
+    public abstract <T extends
+            ToscaElement> Either<T, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex);
 
-    public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> createToscaElement(ToscaElement toscaElement);
+    public abstract <T extends
+            ToscaElement> Either<T, StorageOperationStatus> createToscaElement(ToscaElement toscaElement);
 
-    protected abstract <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement);
+    protected abstract <T extends ToscaElement> TitanOperationStatus
+    setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement);
 
-    protected abstract <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement);
+    protected abstract <T extends ToscaElement> TitanOperationStatus
+    setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement);
 
-    protected abstract <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement);
+    protected abstract <T extends ToscaElement> TitanOperationStatus
+    setRequirementsFromGraph(GraphVertex componentV, T toscaElement);
 
-    protected abstract <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV);
+    protected abstract <T extends ToscaElement> StorageOperationStatus
+    validateCategories(T toscaElementToUpdate, GraphVertex elementV);
 
-    protected abstract <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex updateElementV);
+    protected abstract <T extends ToscaElement> StorageOperationStatus
+    updateDerived(T toscaElementToUpdate, GraphVertex updateElementV);
 
-    public abstract <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag);
+    public abstract <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T
+            toscaElementToUpdate, JsonParseFlagEnum flag);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java
index 168b127..aae7384 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java
@@ -7,9 +7,9 @@
  * 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.
@@ -20,2478 +20,2410 @@
 
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.BiPredicate;
-import java.util.stream.Collectors;
-
+import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
-import org.openecomp.sdc.be.datatypes.elements.MapListCapabiltyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
-import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
-import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
-import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
-import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-import org.openecomp.sdc.be.model.CapabilityDefinition;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceInput;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.ComponentParametersView;
-import org.openecomp.sdc.be.model.DistributionStatusEnum;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.GroupInstance;
-import org.openecomp.sdc.be.model.InputDefinition;
-import org.openecomp.sdc.be.model.LifecycleStateEnum;
-import org.openecomp.sdc.be.model.PolicyDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.RelationshipInfo;
-import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
-import org.openecomp.sdc.be.model.RequirementDefinition;
-import org.openecomp.sdc.be.model.Resource;
-import org.openecomp.sdc.be.model.Service;
-import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.datatypes.elements.*;
+import org.openecomp.sdc.be.datatypes.enums.*;
+import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
+import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
 import org.openecomp.sdc.be.model.catalog.CatalogComponent;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
+import org.openecomp.sdc.be.model.operations.StorageException;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
-import fj.data.Either;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
+
+import static java.util.Objects.requireNonNull;
+import static org.apache.commons.collections.CollectionUtils.isEmpty;
+import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+
 
 @org.springframework.stereotype.Component("tosca-operation-facade")
 public class ToscaOperationFacade {
 
-	// region - Fields
+    // region - Fields
 
-	@Autowired
-	private NodeTypeOperation nodeTypeOperation;
-	@Autowired
-	private TopologyTemplateOperation topologyTemplateOperation;
-	@Autowired
-	private NodeTemplateOperation nodeTemplateOperation;
-	@Autowired
-	private GroupsOperation groupsOperation;
-	@Autowired
-	private TitanDao titanDao;
-	private static Logger log = LoggerFactory.getLogger(ToscaOperationFacade.class.getName());
-	// endregion
+    private static final String COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR = "Couldn't fetch a component with and UniqueId {}, error: {}";
+    private static final String FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS = "Failed to find recently added property {} on the resource {}. Status is {}. ";
+    private static final String FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS = "Failed to get updated resource {}. Status is {}. ";
+    private static final String FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS = "Failed to add the property {} to the resource {}. Status is {}. ";
+    private static final String SERVICE = "service";
+    private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
+    private static final String COMPONENT_CREATED_SUCCESSFULLY = "Component created successfully!!!";
+    private static final String COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR = "Couldn't fetch component with and unique id {}, error: {}";
+    @Autowired
+    private NodeTypeOperation nodeTypeOperation;
+    @Autowired
+    private TopologyTemplateOperation topologyTemplateOperation;
+    @Autowired
+    private NodeTemplateOperation nodeTemplateOperation;
+    @Autowired
+    private GroupsOperation groupsOperation;
+    @Autowired
+    private TitanDao titanDao;
 
-	// region - ToscaElement - GetById
-	public static final String PROXY_SUFFIX = "_proxy";
+    private static final Logger log = Logger.getLogger(ToscaOperationFacade.class.getName());
+    // endregion
 
-	public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(String componentId) {
+    // region - ToscaElement - GetById
+    public static final String PROXY_SUFFIX = "_proxy";
 
-		return getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
+    public <T extends Component> Either<T, StorageOperationStatus> getToscaFullElement(String componentId) {
+        ComponentParametersView filters = new ComponentParametersView();
+        filters.setIgnoreCapabiltyProperties(false);
+        filters.setIgnoreForwardingPath(false);
+        return getToscaElement(componentId, filters);
+    }
 
-	}
+    public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(String componentId) {
 
-	public <T extends Component> Either<T, StorageOperationStatus> getToscaFullElement(String componentId) {
-		ComponentParametersView filters = new ComponentParametersView();
-		filters.setIgnoreCapabiltyProperties(false);
-		filters.setIgnoreForwardingPath(false);
-		return getToscaElement(componentId, filters);
-	}
+        return getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
 
-	public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(String componentId, ComponentParametersView filters) {
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, filters.detectParseFlag());
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+    public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(String componentId, ComponentParametersView filters) {
 
-		}
-		return getToscaElementByOperation(getVertexEither.left().value(), filters);
-	}
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, filters.detectParseFlag());
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
 
-	public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(String componentId, JsonParseFlagEnum parseFlag) {
+        }
+        return getToscaElementByOperation(getVertexEither.left().value(), filters);
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, parseFlag);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+    public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(String componentId, JsonParseFlagEnum parseFlag) {
 
-		}
-		return getToscaElementByOperation(getVertexEither.left().value());
-	}
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, parseFlag);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
 
-	public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(GraphVertex componentVertex) {
-		return getToscaElementByOperation(componentVertex);
-	}
+        }
+        return getToscaElementByOperation(getVertexEither.left().value());
+    }
 
-	public Either<Boolean, StorageOperationStatus> validateComponentExists(String componentId) {
+    public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(GraphVertex componentVertex) {
+        return getToscaElementByOperation(componentVertex);
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			TitanOperationStatus status = getVertexEither.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				return Either.left(false);
-			} else {
-				log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
-			}
-		}
-		return Either.left(true);
-	}
+    public Either<Boolean, StorageOperationStatus> validateComponentExists(String componentId) {
 
-	public <T extends Component> Either<T, StorageOperationStatus> findLastCertifiedToscaElementByUUID(T component) {
-		Map<GraphPropertyEnum, Object> props = new HashMap<>();
-		props.put(GraphPropertyEnum.UUID, component.getUUID());
-		props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
-		props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            TitanOperationStatus status = getVertexEither.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                return Either.left(false);
+            } else {
+                log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+            }
+        }
+        return Either.left(true);
+    }
 
-		Either<List<GraphVertex>, TitanOperationStatus> getVertexEither = titanDao.getByCriteria(ModelConverter.getVertexType(component), props);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", component.getUniqueId(), getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+    public <T extends Component> Either<T, StorageOperationStatus> findLastCertifiedToscaElementByUUID(T component) {
+        Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
+        props.put(GraphPropertyEnum.UUID, component.getUUID());
+        props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
+        props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
 
-		}
-		return getToscaElementByOperation(getVertexEither.left().value().get(0));
-	}
+        Either<List<GraphVertex>, TitanOperationStatus> getVertexEither = titanDao.getByCriteria(ModelConverter.getVertexType(component), props);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, component.getUniqueId(), getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
 
-	// endregion
-	// region - ToscaElement - GetByOperation
-	private <T extends Component> Either<T, StorageOperationStatus> getToscaElementByOperation(GraphVertex componentV) {
-		return getToscaElementByOperation(componentV, new ComponentParametersView());
-	}
+        }
+        return getToscaElementByOperation(getVertexEither.left().value().get(0));
+    }
 
-	private <T extends Component> Either<T, StorageOperationStatus> getToscaElementByOperation(GraphVertex componentV, ComponentParametersView filters) {
-		VertexTypeEnum label = componentV.getLabel();
+    // endregion
+    // region - ToscaElement - GetByOperation
+    private <T extends Component> Either<T, StorageOperationStatus> getToscaElementByOperation(GraphVertex componentV) {
+        return getToscaElementByOperation(componentV, new ComponentParametersView());
+    }
 
-		ToscaElementOperation toscaOperation = getToscaElementOperation(componentV);
-		Either<ToscaElement, StorageOperationStatus> toscaElement;
-		String componentId = componentV.getUniqueId();
-		if (toscaOperation != null) {
-			log.debug("Need to fetch tosca element for id {}", componentId);
- 			toscaElement = toscaOperation.getToscaElement(componentV, filters);
-		} else {
-			log.debug("not supported tosca type {} for id {}", label, componentId);
-			toscaElement = Either.right(StorageOperationStatus.BAD_REQUEST);
-		}
-		if (toscaElement.isRight()) {
-			return Either.right(toscaElement.right().value());
-		}
-		return Either.left(ModelConverter.convertFromToscaElement(toscaElement.left().value()));
-	}
+    private <T extends Component> Either<T, StorageOperationStatus> getToscaElementByOperation(GraphVertex componentV, ComponentParametersView filters) {
+        VertexTypeEnum label = componentV.getLabel();
 
-	// endregion
-	private ToscaElementOperation getToscaElementOperation(GraphVertex componentV) {
-		VertexTypeEnum label = componentV.getLabel();
-		switch (label) {
-		case NODE_TYPE:
-			return nodeTypeOperation;
-		case TOPOLOGY_TEMPLATE:
-			return topologyTemplateOperation;
-		default:
-			return null;
-		}
-	}
+        ToscaElementOperation toscaOperation = getToscaElementOperation(componentV);
+        Either<ToscaElement, StorageOperationStatus> toscaElement;
+        String componentId = componentV.getUniqueId();
+        if (toscaOperation != null) {
+            log.debug("Need to fetch tosca element for id {}", componentId);
+            toscaElement = toscaOperation.getToscaElement(componentV, filters);
+        } else {
+            log.debug("not supported tosca type {} for id {}", label, componentId);
+            toscaElement = Either.right(StorageOperationStatus.BAD_REQUEST);
+        }
+        if (toscaElement.isRight()) {
+            return Either.right(toscaElement.right().value());
+        }
+        return Either.left(ModelConverter.convertFromToscaElement(toscaElement.left().value()));
+    }
 
-	/**
-	 *
-	 * @param resource
-	 * @return
-	 */
-	public <T extends Component> Either<T, StorageOperationStatus> createToscaComponent(T resource) {
-		ToscaElement toscaElement = ModelConverter.convertToToscaElement(resource);
+    // endregion
+    private ToscaElementOperation getToscaElementOperation(GraphVertex componentV) {
+        VertexTypeEnum label = componentV.getLabel();
+        switch (label) {
+            case NODE_TYPE:
+                return nodeTypeOperation;
+            case TOPOLOGY_TEMPLATE:
+                return topologyTemplateOperation;
+            default:
+                return null;
+        }
+    }
 
-		ToscaElementOperation toscaElementOperation = getToscaElementOperation(resource);
-		Either<ToscaElement, StorageOperationStatus> createToscaElement = toscaElementOperation.createToscaElement(toscaElement);
-		if (createToscaElement.isLeft()) {
-			log.debug("Component created successfully!!!");
-			T dataModel = ModelConverter.convertFromToscaElement(createToscaElement.left().value());
-			return Either.left(dataModel);
-		}
-		return Either.right(createToscaElement.right().value());
-	}
+    public <T extends Component> Either<T, StorageOperationStatus> createToscaComponent(T resource) {
+        ToscaElement toscaElement = ModelConverter.convertToToscaElement(resource);
 
-	// region - ToscaElement Delete
-	/**
-	 *
-	 * @param componentToDelete
-	 * @return
-	 */
-	public StorageOperationStatus markComponentToDelete(Component componentToDelete) {
+        ToscaElementOperation toscaElementOperation = getToscaElementOperation(resource);
+        Either<ToscaElement, StorageOperationStatus> createToscaElement = toscaElementOperation.createToscaElement(toscaElement);
+        if (createToscaElement.isLeft()) {
+            log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+            T dataModel = ModelConverter.convertFromToscaElement(createToscaElement.left().value());
+            return Either.left(dataModel);
+        }
+        return Either.right(createToscaElement.right().value());
+    }
 
-		if ((componentToDelete.getIsDeleted() != null) && componentToDelete.getIsDeleted() && !componentToDelete.isHighestVersion()) {
-			// component already marked for delete
-			return StorageOperationStatus.OK;
-		} else {
+    // region - ToscaElement Delete
+    public StorageOperationStatus markComponentToDelete(Component componentToDelete) {
 
-			Either<GraphVertex, TitanOperationStatus> getResponse = titanDao.getVertexById(componentToDelete.getUniqueId(), JsonParseFlagEnum.ParseAll);
-			if (getResponse.isRight()) {
-				log.debug("Couldn't fetch component with and unique id {}, error: {}", componentToDelete.getUniqueId(), getResponse.right().value());
-				return DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value());
+        if ((componentToDelete.getIsDeleted() != null) && componentToDelete.getIsDeleted() && !componentToDelete.isHighestVersion()) {
+            // component already marked for delete
+            return StorageOperationStatus.OK;
+        } else {
 
-			}
-			GraphVertex componentV = getResponse.left().value();
+            Either<GraphVertex, TitanOperationStatus> getResponse = titanDao.getVertexById(componentToDelete.getUniqueId(), JsonParseFlagEnum.ParseAll);
+            if (getResponse.isRight()) {
+                log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentToDelete.getUniqueId(), getResponse.right().value());
+                return DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value());
 
-			// same operation for node type and topology template operations
-			Either<GraphVertex, StorageOperationStatus> result = nodeTypeOperation.markComponentToDelete(componentV);
-			if (result.isRight()) {
-				return result.right().value();
-			}
-			return StorageOperationStatus.OK;
-		}
-	}
+            }
+            GraphVertex componentV = getResponse.left().value();
 
-	/**
-	 *
-	 * @param componentId
-	 * @return
-	 */
-	public <T extends Component> Either<T, StorageOperationStatus> deleteToscaComponent(String componentId) {
+            // same operation for node type and topology template operations
+            Either<GraphVertex, StorageOperationStatus> result = nodeTypeOperation.markComponentToDelete(componentV);
+            if (result.isRight()) {
+                return result.right().value();
+            }
+            return StorageOperationStatus.OK;
+        }
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component vertex with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+    public <T extends Component> Either<T, StorageOperationStatus> deleteToscaComponent(String componentId) {
 
-		}
-		Either<ToscaElement, StorageOperationStatus> deleteElement = deleteToscaElement(getVertexEither.left().value());
-		if (deleteElement.isRight()) {
-			log.debug("Failed to delete component with and unique id {}, error: {}", componentId, deleteElement.right().value());
-			return Either.right(deleteElement.right().value());
-		}
-		T dataModel = ModelConverter.convertFromToscaElement(deleteElement.left().value());
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
+        if (getVertexEither.isRight()) {
+            log.debug("Couldn't fetch component vertex with and unique id {}, error: {}", componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
 
-		return Either.left(dataModel);
-	}
+        }
+        Either<ToscaElement, StorageOperationStatus> deleteElement = deleteToscaElement(getVertexEither.left().value());
+        if (deleteElement.isRight()) {
+            log.debug("Failed to delete component with and unique id {}, error: {}", componentId, deleteElement.right().value());
+            return Either.right(deleteElement.right().value());
+        }
+        T dataModel = ModelConverter.convertFromToscaElement(deleteElement.left().value());
 
-	private Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex componentV) {
-		VertexTypeEnum label = componentV.getLabel();
-		Either<ToscaElement, StorageOperationStatus> toscaElement;
-		Object componentId = componentV.getUniqueId();
-		switch (label) {
-		case NODE_TYPE:
-			log.debug("Need to fetch node type for id {}", componentId);
-			toscaElement = nodeTypeOperation.deleteToscaElement(componentV);
-			break;
-		case TOPOLOGY_TEMPLATE:
-			log.debug("Need to fetch topology template for id {}", componentId);
-			toscaElement = topologyTemplateOperation.deleteToscaElement(componentV);
-			break;
-		default:
-			log.debug("not supported tosca type {} for id {}", label, componentId);
-			toscaElement = Either.right(StorageOperationStatus.BAD_REQUEST);
-			break;
-		}
-		return toscaElement;
-	}
-	// endregion
+        return Either.left(dataModel);
+    }
 
-	private ToscaElementOperation getToscaElementOperation(Component component) {
-		return ModelConverter.isAtomicComponent(component) ? nodeTypeOperation : topologyTemplateOperation;
-	}
+    private Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex componentV) {
+        VertexTypeEnum label = componentV.getLabel();
+        Either<ToscaElement, StorageOperationStatus> toscaElement;
+        Object componentId = componentV.getUniqueId();
+        switch (label) {
+            case NODE_TYPE:
+                log.debug("Need to fetch node type for id {}", componentId);
+                toscaElement = nodeTypeOperation.deleteToscaElement(componentV);
+                break;
+            case TOPOLOGY_TEMPLATE:
+                log.debug("Need to fetch topology template for id {}", componentId);
+                toscaElement = topologyTemplateOperation.deleteToscaElement(componentV);
+                break;
+            default:
+                log.debug("not supported tosca type {} for id {}", label, componentId);
+                toscaElement = Either.right(StorageOperationStatus.BAD_REQUEST);
+                break;
+        }
+        return toscaElement;
+    }
+    // endregion
 
-	public <T extends Component> Either<T, StorageOperationStatus> getLatestByToscaResourceName(String toscaResourceName) {
-		return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
-	}
+    private ToscaElementOperation getToscaElementOperation(Component component) {
+        return ModelConverter.isAtomicComponent(component) ? nodeTypeOperation : topologyTemplateOperation;
+    }
 
-	public <T extends Component> Either<T, StorageOperationStatus> getFullLatestComponentByToscaResourceName(String toscaResourceName) {
-		ComponentParametersView fetchAllFilter = new ComponentParametersView();
-		fetchAllFilter.setIgnoreForwardingPath(true);
-		fetchAllFilter.setIgnoreCapabiltyProperties(false);
-		return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName, JsonParseFlagEnum.ParseAll, fetchAllFilter);
-	}
+    public <T extends Component> Either<T, StorageOperationStatus> getLatestByToscaResourceName(String toscaResourceName) {
+        return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
+    }
 
-	public <T extends Component> Either<T, StorageOperationStatus> getLatestByName(String resourceName) {
-		return getLatestByName(GraphPropertyEnum.NAME, resourceName);
+    public <T extends Component> Either<T, StorageOperationStatus> getFullLatestComponentByToscaResourceName(String toscaResourceName) {
+        ComponentParametersView fetchAllFilter = new ComponentParametersView();
+        fetchAllFilter.setIgnoreForwardingPath(true);
+        fetchAllFilter.setIgnoreCapabiltyProperties(false);
+        return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName, JsonParseFlagEnum.ParseAll, fetchAllFilter);
+    }
 
-	}
+    public <T extends Component> Either<T, StorageOperationStatus> getLatestByName(String resourceName) {
+        return getLatestByName(GraphPropertyEnum.NAME, resourceName);
 
-	public Either<Integer, StorageOperationStatus> validateCsarUuidUniqueness(String csarUUID) {
+    }
 
-		Map<GraphPropertyEnum, Object> properties = new HashMap<GraphPropertyEnum, Object>();
-		properties.put(GraphPropertyEnum.CSAR_UUID, csarUUID);
+    public StorageOperationStatus validateCsarUuidUniqueness(String csarUUID) {
 
-		Either<List<GraphVertex>, TitanOperationStatus> resources = titanDao.getByCriteria(null, properties, JsonParseFlagEnum.ParseMetadata);
+        Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
+        properties.put(GraphPropertyEnum.CSAR_UUID, csarUUID);
 
-		if (resources.isRight()) {
-			if (resources.right().value() == TitanOperationStatus.NOT_FOUND) {
-				return Either.left(new Integer(0));
-			} else {
-				log.debug("failed to get resources from graph with property name: {}", csarUUID);
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resources.right().value()));
-			}
-		}
+        Either<List<GraphVertex>, TitanOperationStatus> resources = titanDao.getByCriteria(null, properties, JsonParseFlagEnum.ParseMetadata);
 
-		List<GraphVertex> resourceList = (resources.isLeft() ? resources.left().value() : null);
+        if (resources.isRight()) {
+            if (resources.right().value() == TitanOperationStatus.NOT_FOUND) {
+                return StorageOperationStatus.OK;
+            } else {
+                log.debug("failed to get resources from graph with property name: {}", csarUUID);
+                return DaoStatusConverter.convertTitanStatusToStorageStatus(resources.right().value());
+            }
+        }
+        return StorageOperationStatus.ENTITY_ALREADY_EXISTS;
 
-		return Either.left(new Integer(resourceList.size()));
+    }
 
-	}
+    public <T extends Component> Either<Set<T>, StorageOperationStatus> getFollowed(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, ComponentTypeEnum componentType) {
+        Either<List<ToscaElement>, StorageOperationStatus> followedResources;
+        if (componentType == ComponentTypeEnum.RESOURCE) {
+            followedResources = nodeTypeOperation.getFollowedComponent(userId, lifecycleStates, lastStateStates, componentType);
+        } else {
+            followedResources = topologyTemplateOperation.getFollowedComponent(userId, lifecycleStates, lastStateStates, componentType);
+        }
 
-	public <T extends Component> Either<Set<T>, StorageOperationStatus> getFollowed(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, ComponentTypeEnum componentType) {
-		Either<List<ToscaElement>, StorageOperationStatus> followedResources;
-		if (componentType == ComponentTypeEnum.RESOURCE) {
-			followedResources = nodeTypeOperation.getFollowedComponent(userId, lifecycleStates, lastStateStates, componentType);
-		} else {
-			followedResources = topologyTemplateOperation.getFollowedComponent(userId, lifecycleStates, lastStateStates, componentType);
-		}
+        Set<T> components = new HashSet<>();
+        if (followedResources.isRight() && followedResources.right().value() != StorageOperationStatus.NOT_FOUND) {
+            return Either.right(followedResources.right().value());
+        }
+        if (followedResources.isLeft()) {
+            List<ToscaElement> toscaElements = followedResources.left().value();
+            toscaElements.forEach(te -> {
+                T component = ModelConverter.convertFromToscaElement(te);
+                components.add(component);
+            });
+        }
+        return Either.left(components);
+    }
 
-		Set<T> components = new HashSet<>();
-		if (followedResources.isRight() && followedResources.right().value() != StorageOperationStatus.NOT_FOUND) {
-			return Either.right(followedResources.right().value());
-		}
-		if (followedResources.isLeft()) {
-			List<ToscaElement> toscaElements = followedResources.left().value();
-			toscaElements.forEach(te -> {
-				T component = ModelConverter.convertFromToscaElement(te);
-				components.add(component);
-			});
-		}
-		return Either.left(components);
-	}
+    public Either<Resource, StorageOperationStatus> getLatestCertifiedNodeTypeByToscaResourceName(String toscaResourceName) {
 
-	public Either<Resource, StorageOperationStatus> getLatestCertifiedNodeTypeByToscaResourceName(String toscaResourceName) {
+        return getLatestCertifiedByToscaResourceName(toscaResourceName, VertexTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata);
+    }
 
-		return getLatestCertifiedByToscaResourceName(toscaResourceName, VertexTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata);
-	}
+    public Either<Resource, StorageOperationStatus> getLatestCertifiedByToscaResourceName(String toscaResourceName, VertexTypeEnum vertexType, JsonParseFlagEnum parseFlag) {
 
-	public Either<Resource, StorageOperationStatus> getLatestCertifiedByToscaResourceName(String toscaResourceName, VertexTypeEnum vertexType, JsonParseFlagEnum parseFlag) {
+        Either<Resource, StorageOperationStatus> result = null;
+        Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
+        props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
+        props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
+        Either<List<GraphVertex>, TitanOperationStatus> getLatestRes = titanDao.getByCriteria(vertexType, props, parseFlag);
 
-		Either<Resource, StorageOperationStatus> result = null;
-		Map<GraphPropertyEnum, Object> props = new HashMap<GraphPropertyEnum, Object>();
-		props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
-		props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
-		props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
-		Either<List<GraphVertex>, TitanOperationStatus> getLatestRes = titanDao.getByCriteria(vertexType, props, parseFlag);
+        if (getLatestRes.isRight()) {
+            TitanOperationStatus status = getLatestRes.right().value();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch {} with name {}. status={} ", vertexType, toscaResourceName, status);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        if (result == null) {
+            List<GraphVertex> resources = getLatestRes.left().value();
+            double version = 0.0;
+            GraphVertex highestResource = null;
+            for (GraphVertex resource : resources) {
+                double resourceVersion = Double.parseDouble((String) resource.getJsonMetadataField(JsonPresentationFields.VERSION));
+                if (resourceVersion > version) {
+                    version = resourceVersion;
+                    highestResource = resource;
+                }
+            }
+            result = getToscaFullElement(highestResource.getUniqueId());
+        }
+        return result;
+    }
 
-		if (getLatestRes.isRight()) {
-			TitanOperationStatus status = getLatestRes.right().value();
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch {} with name {}. status={} ", vertexType, toscaResourceName, status);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		if (result == null) {
-			List<GraphVertex> resources = getLatestRes.left().value();
-			double version = 0.0;
-			GraphVertex highestResource = null;
-			for (GraphVertex resource : resources) {
-				double resourceVersion = Double.parseDouble((String) resource.getJsonMetadataField(JsonPresentationFields.VERSION));
-				if (resourceVersion > version) {
-					version = resourceVersion;
-					highestResource = resource;
-				}
-			}
-			result = getToscaFullElement(highestResource.getUniqueId());
-		}
-		return result;
-	}
+    public Either<Boolean, StorageOperationStatus> validateToscaResourceNameExists(String templateName) {
+        Either<Boolean, StorageOperationStatus> validateUniquenessRes = validateToscaResourceNameUniqueness(templateName);
+        if (validateUniquenessRes.isLeft()) {
+            return Either.left(!validateUniquenessRes.left().value());
+        }
+        return validateUniquenessRes;
+    }
 
-	public Either<Boolean, StorageOperationStatus> validateToscaResourceNameExists(String templateName) {
-		Either<Boolean, StorageOperationStatus> validateUniquenessRes = validateToscaResourceNameUniqueness(templateName);
-		if (validateUniquenessRes.isLeft()) {
-			return Either.left(!validateUniquenessRes.left().value());
-		}
-		return validateUniquenessRes;
-	}
+    public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId, RequirementCapabilityRelDef requirementDef) {
+        return nodeTemplateOperation.dissociateResourceInstances(componentId, requirementDef);
+    }
 
-	public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId, RequirementCapabilityRelDef requirementDef) {
-		return nodeTemplateOperation.dissociateResourceInstances(componentId, requirementDef);
-	}
-	/**
-	 * Allows to get fulfilled requirement by relation and received predicate
-	 * @param componentId
-	 * @param instanceId
-	 * @param relation
-	 * @param predicate
-	 * @return
-	 */
-	public Either<RequirementDataDefinition, StorageOperationStatus> getFulfilledRequirementByRelation(String componentId, String instanceId, RequirementCapabilityRelDef relation, BiPredicate<RelationshipInfo, RequirementDataDefinition> predicate) {
-		return nodeTemplateOperation.getFulfilledRequirementByRelation(componentId, instanceId, relation, predicate);
-	}
-	/**
-	 * Allows to get fulfilled capability by relation and received predicate
-	 * @param componentId
-	 * @param instanceId
-	 * @param relation
-	 * @param predicate
-	 * @return
-	 */
-	public Either<CapabilityDataDefinition, StorageOperationStatus> getFulfilledCapabilityByRelation(String componentId, String instanceId, RequirementCapabilityRelDef relation, BiPredicate<RelationshipInfo, CapabilityDataDefinition> predicate) {
-		return nodeTemplateOperation.getFulfilledCapabilityByRelation(componentId, instanceId, relation, predicate);
-	}
+    /**
+     * Allows to get fulfilled requirement by relation and received predicate
+     */
+    public Either<RequirementDataDefinition, StorageOperationStatus> getFulfilledRequirementByRelation(String componentId, String instanceId, RequirementCapabilityRelDef relation, BiPredicate<RelationshipInfo, RequirementDataDefinition> predicate) {
+        return nodeTemplateOperation.getFulfilledRequirementByRelation(componentId, instanceId, relation, predicate);
+    }
 
-	public StorageOperationStatus associateResourceInstances(String componentId, List<RequirementCapabilityRelDef> relations) {
-		Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> status = nodeTemplateOperation.associateResourceInstances(componentId, relations);
-		if (status.isRight()) {
-			return status.right().value();
-		}
-		return StorageOperationStatus.OK;
-	}
+    /**
+     * Allows to get fulfilled capability by relation and received predicate
+     */
+    public Either<CapabilityDataDefinition, StorageOperationStatus> getFulfilledCapabilityByRelation(String componentId, String instanceId, RequirementCapabilityRelDef relation, BiPredicate<RelationshipInfo, CapabilityDataDefinition> predicate) {
+        return nodeTemplateOperation.getFulfilledCapabilityByRelation(componentId, instanceId, relation, predicate);
+    }
 
-	protected Either<Boolean, StorageOperationStatus> validateToscaResourceNameUniqueness(String name) {
+    public StorageOperationStatus associateResourceInstances(String componentId, List<RequirementCapabilityRelDef> relations) {
+        Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> status = nodeTemplateOperation.associateResourceInstances(componentId, relations);
+        if (status.isRight()) {
+            return status.right().value();
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		Map<GraphPropertyEnum, Object> properties = new HashMap<GraphPropertyEnum, Object>();
-		properties.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, name);
+    protected Either<Boolean, StorageOperationStatus> validateToscaResourceNameUniqueness(String name) {
 
-		Either<List<GraphVertex>, TitanOperationStatus> resources = titanDao.getByCriteria(null, properties, JsonParseFlagEnum.ParseMetadata);
+        Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
+        properties.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, name);
 
-		if (resources.isRight() && resources.right().value() != TitanOperationStatus.NOT_FOUND) {
-			log.debug("failed to get resources from graph with property name: {}", name);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resources.right().value()));
-		}
-		List<GraphVertex> resourceList = (resources.isLeft() ? resources.left().value() : null);
-		if (resourceList != null && resourceList.size() > 0) {
-			if (log.isDebugEnabled()) {
-				StringBuilder builder = new StringBuilder();
-				for (GraphVertex resourceData : resourceList) {
-					builder.append(resourceData.getUniqueId() + "|");
-				}
-				log.debug("resources  with property name:{} exists in graph. found {}", name, builder.toString());
-			}
-			return Either.left(false);
-		} else {
-			log.debug("resources  with property name:{} does not exists in graph", name);
-			return Either.left(true);
-		}
+        Either<List<GraphVertex>, TitanOperationStatus> resources = titanDao.getByCriteria(null, properties, JsonParseFlagEnum.ParseMetadata);
 
-	}
+        if (resources.isRight() && resources.right().value() != TitanOperationStatus.NOT_FOUND) {
+            log.debug("failed to get resources from graph with property name: {}", name);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resources.right().value()));
+        }
+        List<GraphVertex> resourceList = (resources.isLeft() ? resources.left().value() : null);
+        if (isNotEmpty(resourceList)) {
+            if (log.isDebugEnabled()) {
+                StringBuilder builder = new StringBuilder();
+                for (GraphVertex resourceData : resourceList) {
+                    builder.append(resourceData.getUniqueId() + "|");
+                }
+                log.debug("resources  with property name:{} exists in graph. found {}", name, builder);
+            }
+            return Either.left(false);
+        } else {
+            log.debug("resources  with property name:{} does not exists in graph", name);
+            return Either.left(true);
+        }
 
-	// region - Component Update
-	/**
-	 *
-	 * @param newComponent
-	 * @param oldComponent
-	 * @return vendor
-	 */
-	public Either<Resource, StorageOperationStatus> overrideComponent(Resource newComponent, Resource oldComponent) {
+    }
 
-		// TODO
-		// newComponent.setInterfaces(oldComponent.getInterfaces);
-		newComponent.setArtifacts(oldComponent.getArtifacts());
-		newComponent.setDeploymentArtifacts(oldComponent.getDeploymentArtifacts());
-		newComponent.setGroups(oldComponent.getGroups());
-		newComponent.setLastUpdateDate(null);
-		newComponent.setHighestVersion(true);
+    // region - Component Update
 
-		Either<GraphVertex, TitanOperationStatus> componentVEither = titanDao.getVertexById(oldComponent.getUniqueId(), JsonParseFlagEnum.NoParse);
-		if (componentVEither.isRight()) {
-			log.debug("Falied to fetch component {} error {}", oldComponent.getUniqueId(), componentVEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(componentVEither.right().value()));
-		}
-		GraphVertex componentv = componentVEither.left().value();
-		Either<GraphVertex, TitanOperationStatus> parentVertexEither = titanDao.getParentVertex(componentv, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
-		if (parentVertexEither.isRight() && parentVertexEither.right().value() != TitanOperationStatus.NOT_FOUND) {
-			log.debug("Falied to fetch parent version for component {} error {}", oldComponent.getUniqueId(), parentVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentVertexEither.right().value()));
-		}
+    public Either<Resource, StorageOperationStatus> overrideComponent(Resource newComponent, Resource oldComponent) {
 
-		Either<ToscaElement, StorageOperationStatus> deleteToscaComponent = deleteToscaElement(componentv);
-		if (deleteToscaComponent.isRight()) {
-			log.debug("Falied to remove old component {} error {}", oldComponent.getUniqueId(), deleteToscaComponent.right().value());
-			return Either.right(deleteToscaComponent.right().value());
-		}
-		Either<Resource, StorageOperationStatus> createToscaComponent = createToscaComponent(newComponent);
-		if (createToscaComponent.isRight()) {
-			log.debug("Falied to create tosca element component {} error {}", newComponent.getUniqueId(), createToscaComponent.right().value());
-			return Either.right(createToscaComponent.right().value());
-		}
-		Resource newElement = createToscaComponent.left().value();
-		Either<GraphVertex, TitanOperationStatus> newVersionEither = titanDao.getVertexById(newElement.getUniqueId(), JsonParseFlagEnum.NoParse);
-		if (newVersionEither.isRight()) {
-			log.debug("Falied to fetch new tosca element component {} error {}", newComponent.getUniqueId(), newVersionEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(newVersionEither.right().value()));
-		}
-		if (parentVertexEither.isLeft()) {
-			GraphVertex previousVersionV = parentVertexEither.left().value();
-			TitanOperationStatus createEdge = titanDao.createEdge(previousVersionV, newVersionEither.left().value(), EdgeLabelEnum.VERSION, null);
-			if (createEdge != TitanOperationStatus.OK) {
-				log.debug("Falied to associate to previous version {} new version {} error {}", previousVersionV.getUniqueId(), newVersionEither.right().value(), createEdge);
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge));
-			}
-		}
-		return Either.left(newElement);
-	}
+        copyArtifactsToNewComponent(newComponent, oldComponent);
 
-	/**
-	 *
-	 * @param componentToUpdate
-	 * @return
-	 */
-	public <T extends Component> Either<T, StorageOperationStatus> updateToscaElement(T componentToUpdate) {
-		return updateToscaElement(componentToUpdate, new ComponentParametersView());
-	}
+        Either<GraphVertex, TitanOperationStatus> componentVEither = titanDao.getVertexById(oldComponent.getUniqueId(), JsonParseFlagEnum.NoParse);
+        if (componentVEither.isRight()) {
+            log.debug("Falied to fetch component {} error {}", oldComponent.getUniqueId(), componentVEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(componentVEither.right().value()));
+        }
+        GraphVertex componentv = componentVEither.left().value();
+        Either<GraphVertex, TitanOperationStatus> parentVertexEither = titanDao.getParentVertex(componentv, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
+        if (parentVertexEither.isRight() && parentVertexEither.right().value() != TitanOperationStatus.NOT_FOUND) {
+            log.debug("Falied to fetch parent version for component {} error {}", oldComponent.getUniqueId(), parentVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentVertexEither.right().value()));
+        }
 
-	/**
-	 *
-	 * @param componentToUpdate
-	 * @param type
-	 * @param filterResult
-	 * @return
-	 */
-	public <T extends Component> Either<T, StorageOperationStatus> updateToscaElement(T componentToUpdate, ComponentParametersView filterResult) {
-		String componentId = componentToUpdate.getUniqueId();
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
-		}
-		GraphVertex elementV = getVertexEither.left().value();
-		ToscaElementOperation toscaElementOperation = getToscaElementOperation(elementV);
+        Either<ToscaElement, StorageOperationStatus> deleteToscaComponent = deleteToscaElement(componentv);
+        if (deleteToscaComponent.isRight()) {
+            log.debug("Falied to remove old component {} error {}", oldComponent.getUniqueId(), deleteToscaComponent.right().value());
+            return Either.right(deleteToscaComponent.right().value());
+        }
+        Either<Resource, StorageOperationStatus> createToscaComponent = createToscaComponent(newComponent);
+        if (createToscaComponent.isRight()) {
+            log.debug("Falied to create tosca element component {} error {}", newComponent.getUniqueId(), createToscaComponent.right().value());
+            return Either.right(createToscaComponent.right().value());
+        }
+        Resource newElement = createToscaComponent.left().value();
+        Either<GraphVertex, TitanOperationStatus> newVersionEither = titanDao.getVertexById(newElement.getUniqueId(), JsonParseFlagEnum.NoParse);
+        if (newVersionEither.isRight()) {
+            log.debug("Falied to fetch new tosca element component {} error {}", newComponent.getUniqueId(), newVersionEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(newVersionEither.right().value()));
+        }
+        if (parentVertexEither.isLeft()) {
+            GraphVertex previousVersionV = parentVertexEither.left().value();
+            TitanOperationStatus createEdge = titanDao.createEdge(previousVersionV, newVersionEither.left().value(), EdgeLabelEnum.VERSION, null);
+            if (createEdge != TitanOperationStatus.OK) {
+                log.debug("Falied to associate to previous version {} new version {} error {}", previousVersionV.getUniqueId(), newVersionEither.right().value(), createEdge);
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge));
+            }
+        }
+        return Either.left(newElement);
+    }
 
-		ToscaElement toscaElementToUpdate = ModelConverter.convertToToscaElement(componentToUpdate);
-		Either<ToscaElement, StorageOperationStatus> updateToscaElement = toscaElementOperation.updateToscaElement(toscaElementToUpdate, elementV, filterResult);
-		if (updateToscaElement.isRight()) {
-			log.debug("Failed to update tosca element {} error {}", componentId, updateToscaElement.right().value());
-			return Either.right(updateToscaElement.right().value());
-		}
-		return Either.left(ModelConverter.convertFromToscaElement(updateToscaElement.left().value()));
-	}
+    void copyArtifactsToNewComponent(Resource newComponent, Resource oldComponent) {
+        // TODO - check if required
+        Map<String, ArtifactDefinition> toscaArtifacts = oldComponent.getToscaArtifacts();
+        if (toscaArtifacts != null && !toscaArtifacts.isEmpty()) {
+            toscaArtifacts.values().stream().forEach(a -> a.setDuplicated(Boolean.TRUE));
+        }
+        newComponent.setToscaArtifacts(toscaArtifacts);
 
-	private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName, JsonParseFlagEnum parseFlag) {
-		return getLatestByName(property, nodeName, parseFlag, new ComponentParametersView());
-	}
+        Map<String, ArtifactDefinition> artifacts = oldComponent.getArtifacts();
+        if (artifacts != null && !artifacts.isEmpty()) {
+            artifacts.values().stream().forEach(a -> a.setDuplicated(Boolean.TRUE));
+        }
+        newComponent.setArtifacts(artifacts);
 
-	private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName, JsonParseFlagEnum parseFlag, ComponentParametersView filter) {
-		Either<T, StorageOperationStatus> result;
+        Map<String, ArtifactDefinition> depArtifacts = oldComponent.getDeploymentArtifacts();
+        if (depArtifacts != null && !depArtifacts.isEmpty()) {
+            depArtifacts.values().stream().forEach(a -> a.setDuplicated(Boolean.TRUE));
+        }
+        newComponent.setDeploymentArtifacts(depArtifacts);
 
-		Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
-		Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        newComponent.setGroups(oldComponent.getGroups());
+        newComponent.setLastUpdateDate(null);
+        newComponent.setHighestVersion(true);
+    }
 
-		propertiesToMatch.put(property, nodeName);
-		propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+    public <T extends Component> Either<T, StorageOperationStatus> updateToscaElement(T componentToUpdate) {
+        return updateToscaElement(componentToUpdate, new ComponentParametersView());
+    }
 
-		propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+    public <T extends Component> Either<T, StorageOperationStatus> updateToscaElement(T componentToUpdate, ComponentParametersView filterResult) {
+        String componentId = componentToUpdate.getUniqueId();
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+        }
+        GraphVertex elementV = getVertexEither.left().value();
+        ToscaElementOperation toscaElementOperation = getToscaElementOperation(elementV);
 
-		Either<List<GraphVertex>, TitanOperationStatus> highestResources = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, parseFlag);
-		if (highestResources.isRight()) {
-			TitanOperationStatus status = highestResources.right().value();
-			log.debug("failed to find resource with name {}. status={} ", nodeName, status);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			return result;
-		}
+        ToscaElement toscaElementToUpdate = ModelConverter.convertToToscaElement(componentToUpdate);
+        Either<ToscaElement, StorageOperationStatus> updateToscaElement = toscaElementOperation.updateToscaElement(toscaElementToUpdate, elementV, filterResult);
+        if (updateToscaElement.isRight()) {
+            log.debug("Failed to update tosca element {} error {}", componentId, updateToscaElement.right().value());
+            return Either.right(updateToscaElement.right().value());
+        }
+        return Either.left(ModelConverter.convertFromToscaElement(updateToscaElement.left().value()));
+    }
 
-		List<GraphVertex> resources = highestResources.left().value();
-		double version = 0.0;
-		GraphVertex highestResource = null;
-		for (GraphVertex vertex : resources) {
-			Object versionObj = vertex.getMetadataProperty(GraphPropertyEnum.VERSION);
-			double resourceVersion = Double.valueOf((String) versionObj);
-			if (resourceVersion > version) {
-				version = resourceVersion;
-				highestResource = vertex;
-			}
-		}
-		return getToscaElementByOperation(highestResource, filter);
-	}
+    private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName, JsonParseFlagEnum parseFlag) {
+        return getLatestByName(property, nodeName, parseFlag, new ComponentParametersView());
+    }
 
-	// endregion
-	// region - Component Get By ..
-	private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName) {
-		return getLatestByName(property, nodeName, JsonParseFlagEnum.ParseMetadata);
-	}
+    private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName, JsonParseFlagEnum parseFlag, ComponentParametersView filter) {
+        Either<T, StorageOperationStatus> result;
 
-	public <T extends Component> Either<List<T>, StorageOperationStatus> getBySystemName(ComponentTypeEnum componentType, String systemName) {
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
 
-		Either<List<T>, StorageOperationStatus> result = null;
-		Either<T, StorageOperationStatus> getComponentRes;
-		List<T> components = new ArrayList<>();
-		List<GraphVertex> componentVertices;
-		Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
-		Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        propertiesToMatch.put(property, nodeName);
+        propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
 
-		propertiesToMatch.put(GraphPropertyEnum.SYSTEM_NAME, systemName);
-		if (componentType != null)
-			propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
+        propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
 
-		propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+        Either<List<GraphVertex>, TitanOperationStatus> highestResources = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, parseFlag);
+        if (highestResources.isRight()) {
+            TitanOperationStatus status = highestResources.right().value();
+            log.debug("failed to find resource with name {}. status={} ", nodeName, status);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            return result;
+        }
 
-		Either<List<GraphVertex>, TitanOperationStatus> getComponentsRes = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
-		if (getComponentsRes.isRight()) {
-			TitanOperationStatus status = getComponentsRes.right().value();
-			log.debug("Failed to fetch the component with system name {}. Status is {} ", systemName, status);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		if (result == null) {
-			componentVertices = getComponentsRes.left().value();
-			for (GraphVertex componentVertex : componentVertices) {
-				getComponentRes = getToscaElementByOperation(componentVertex);
-				if (getComponentRes.isRight()) {
-					log.debug("Failed to get the component {}. Status is {} ", componentVertex.getJsonMetadataField(JsonPresentationFields.NAME), getComponentRes.right().value());
-					result = Either.right(getComponentRes.right().value());
-					break;
-				}
-				T componentBySystemName = getComponentRes.left().value();
-				log.debug("Found component, id: {}", componentBySystemName.getUniqueId());
-				components.add(componentBySystemName);
-			}
-		}
-		if (result == null) {
-			result = Either.left(components);
-		}
-		return result;
-	}
+        List<GraphVertex> resources = highestResources.left().value();
+        double version = 0.0;
+        GraphVertex highestResource = null;
+        for (GraphVertex vertex : resources) {
+            Object versionObj = vertex.getMetadataProperty(GraphPropertyEnum.VERSION);
+            double resourceVersion = Double.parseDouble((String) versionObj);
+            if (resourceVersion > version) {
+                version = resourceVersion;
+                highestResource = vertex;
+            }
+        }
+        return getToscaElementByOperation(highestResource, filter);
+    }
 
-	public <T extends Component> Either<T, StorageOperationStatus> getComponentByNameAndVersion(ComponentTypeEnum componentType, String name, String version) {
-		return getComponentByNameAndVersion(componentType, name, version, JsonParseFlagEnum.ParseAll);
-	}
+    // endregion
+    // region - Component Get By ..
+    private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName) {
+        return getLatestByName(property, nodeName, JsonParseFlagEnum.ParseMetadata);
+    }
 
-	public <T extends Component> Either<T, StorageOperationStatus> getComponentByNameAndVersion(ComponentTypeEnum componentType, String name, String version, JsonParseFlagEnum parseFlag) {
-		Either<T, StorageOperationStatus> result;
+    public <T extends Component> Either<List<T>, StorageOperationStatus> getBySystemName(ComponentTypeEnum componentType, String systemName) {
 
-		Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
-		Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
+        Either<List<T>, StorageOperationStatus> result = null;
+        Either<T, StorageOperationStatus> getComponentRes;
+        List<T> components = new ArrayList<>();
+        List<GraphVertex> componentVertices;
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
 
-		hasProperties.put(GraphPropertyEnum.NAME, name);
-		hasProperties.put(GraphPropertyEnum.VERSION, version);
-		hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true);
-		if (componentType != null) {
-			hasProperties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
-		}
-		Either<List<GraphVertex>, TitanOperationStatus> getResourceRes = titanDao.getByCriteria(null, hasProperties, hasNotProperties, parseFlag);
-		if (getResourceRes.isRight()) {
-			TitanOperationStatus status = getResourceRes.right().value();
-			log.debug("failed to find resource with name {}, version {}. Status is {} ", name, version, status);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			return result;
-		}
-		return getToscaElementByOperation(getResourceRes.left().value().get(0));
-	}
-	public Either<List<CatalogComponent>, StorageOperationStatus> getCatalogComponents() {
-		return topologyTemplateOperation.getElementCatalogData();
-	}
+        propertiesToMatch.put(GraphPropertyEnum.SYSTEM_NAME, systemName);
+        if (componentType != null)
+            propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
 
-	// endregion
-	public <T extends Component> Either<List<T>, StorageOperationStatus> getCatalogComponents(ComponentTypeEnum componentType, List<OriginTypeEnum> excludeTypes, boolean isHighestVersions) {
-		List<T> components = new ArrayList<>();
-		Either<List<ToscaElement>, StorageOperationStatus> catalogDataResult;
-		List<ToscaElement> toscaElements = new ArrayList<>();
-		List<ResourceTypeEnum> excludedResourceTypes = Optional.ofNullable(excludeTypes).orElse(Collections.emptyList()).stream().filter(type -> !type.equals(OriginTypeEnum.SERVICE)).map(type -> ResourceTypeEnum.getTypeByName(type.name()))
-				.collect(Collectors.toList());
+        propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
 
-		switch (componentType) {
-		case RESOURCE:
-			catalogDataResult = nodeTypeOperation.getElementCatalogData(ComponentTypeEnum.RESOURCE, excludedResourceTypes, isHighestVersions);
-			if (catalogDataResult.isRight()) {
-				return Either.right(catalogDataResult.right().value());
-			}
-			toscaElements = catalogDataResult.left().value();
-			break;
-		case SERVICE:
-			if (excludeTypes != null && excludeTypes.contains(OriginTypeEnum.SERVICE)) {
-				break;
-			}
-			catalogDataResult = topologyTemplateOperation.getElementCatalogData(ComponentTypeEnum.SERVICE, null, isHighestVersions);
-			if (catalogDataResult.isRight()) {
-				return Either.right(catalogDataResult.right().value());
-			}
-			toscaElements = catalogDataResult.left().value();
-			break;
-		default:
-			log.debug("Not supported component type {}", componentType);
-			return Either.right(StorageOperationStatus.BAD_REQUEST);
-		}
-		toscaElements.forEach(te -> {
-			T component = ModelConverter.convertFromToscaElement(te);
-			components.add(component);
-		});
-		return Either.left(components);
-	}
+        Either<List<GraphVertex>, TitanOperationStatus> getComponentsRes = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
+        if (getComponentsRes.isRight()) {
+            TitanOperationStatus status = getComponentsRes.right().value();
+            log.debug("Failed to fetch the component with system name {}. Status is {} ", systemName, status);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        if (result == null) {
+            componentVertices = getComponentsRes.left().value();
+            for (GraphVertex componentVertex : componentVertices) {
+                getComponentRes = getToscaElementByOperation(componentVertex);
+                if (getComponentRes.isRight()) {
+                    log.debug("Failed to get the component {}. Status is {} ", componentVertex.getJsonMetadataField(JsonPresentationFields.NAME), getComponentRes.right().value());
+                    result = Either.right(getComponentRes.right().value());
+                    break;
+                }
+                T componentBySystemName = getComponentRes.left().value();
+                log.debug("Found component, id: {}", componentBySystemName.getUniqueId());
+                components.add(componentBySystemName);
+            }
+        }
+        if (result == null) {
+            result = Either.left(components);
+        }
+        return result;
+    }
 
-	public Either<List<String>, StorageOperationStatus> deleteMarkedElements(ComponentTypeEnum componentType) {
-		Either<List<GraphVertex>, StorageOperationStatus> allComponentsMarkedForDeletion;
-		List<String> deleted = new ArrayList<>();
-		switch (componentType) {
-		case RESOURCE:
-			allComponentsMarkedForDeletion = nodeTypeOperation.getAllComponentsMarkedForDeletion(componentType);
-			break;
-		case SERVICE:
-		case PRODUCT:
-			allComponentsMarkedForDeletion = topologyTemplateOperation.getAllComponentsMarkedForDeletion(componentType);
-			break;
-		default:
-			log.debug("Not supported component type {}", componentType);
-			return Either.right(StorageOperationStatus.BAD_REQUEST);
-		}
-		if (allComponentsMarkedForDeletion.isRight()) {
-			return Either.right(allComponentsMarkedForDeletion.right().value());
-		}
-		List<GraphVertex> allMarked = allComponentsMarkedForDeletion.left().value();
+    public <T extends Component> Either<T, StorageOperationStatus> getComponentByNameAndVersion(ComponentTypeEnum componentType, String name, String version) {
+        return getComponentByNameAndVersion(componentType, name, version, JsonParseFlagEnum.ParseAll);
+    }
 
-		Either<List<GraphVertex>, TitanOperationStatus> allNotDeletedElements = topologyTemplateOperation.getAllNotDeletedElements();
-		if (allNotDeletedElements.isRight()) {
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(allNotDeletedElements.right().value()));
-		}
-		List<GraphVertex> allNonMarked = allNotDeletedElements.left().value();
-		for (GraphVertex elementV : allMarked) {
-			if (topologyTemplateOperation.isInUse(elementV, allNonMarked) == false) {
-				Either<ToscaElement, StorageOperationStatus> deleteToscaElement = deleteToscaElement(elementV);
-				if (deleteToscaElement.isRight()) {
-					log.debug("Failed to delete marked element {} error {}", elementV.getUniqueId(), deleteToscaElement.right().value());
-				}
-			} else {
-				deleted.add(elementV.getUniqueId());
-				log.debug("Marked element {} in use. don't delete it", elementV.getUniqueId());
-			}
-		}
-		return Either.left(deleted);
-	}
+    public <T extends Component> Either<T, StorageOperationStatus> getComponentByNameAndVersion(ComponentTypeEnum componentType, String name, String version, JsonParseFlagEnum parseFlag) {
+        Either<T, StorageOperationStatus> result;
 
-	public Either<List<String>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
-		Either<List<GraphVertex>, StorageOperationStatus> allComponentsMarkedForDeletion;
-		switch (componentType) {
-		case RESOURCE:
-			allComponentsMarkedForDeletion = nodeTypeOperation.getAllComponentsMarkedForDeletion(componentType);
-			break;
-		case SERVICE:
-		case PRODUCT:
-			allComponentsMarkedForDeletion = topologyTemplateOperation.getAllComponentsMarkedForDeletion(componentType);
-			break;
-		default:
-			log.debug("Not supported component type {}", componentType);
-			return Either.right(StorageOperationStatus.BAD_REQUEST);
-		}
-		if (allComponentsMarkedForDeletion.isRight()) {
-			return Either.right(allComponentsMarkedForDeletion.right().value());
-		}
-		return Either.left(allComponentsMarkedForDeletion.left().value().stream().map(v -> v.getUniqueId()).collect(Collectors.toList()));
-	}
+        Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
+        Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
 
-	public Either<Boolean, StorageOperationStatus> isComponentInUse(String componentId) {
-		Either<Boolean, StorageOperationStatus> result;
-		Either<List<GraphVertex>, TitanOperationStatus> allNotDeletedElements = topologyTemplateOperation.getAllNotDeletedElements();
-		if (allNotDeletedElements.isRight()) {
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(allNotDeletedElements.right().value()));
-		} else {
-			result = Either.left(topologyTemplateOperation.isInUse(componentId, allNotDeletedElements.left().value()));
-		}
-		return result;
-	}
+        hasProperties.put(GraphPropertyEnum.NAME, name);
+        hasProperties.put(GraphPropertyEnum.VERSION, version);
+        hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true);
+        if (componentType != null) {
+            hasProperties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
+        }
+        Either<List<GraphVertex>, TitanOperationStatus> getResourceRes = titanDao.getByCriteria(null, hasProperties, hasNotProperties, parseFlag);
+        if (getResourceRes.isRight()) {
+            TitanOperationStatus status = getResourceRes.right().value();
+            log.debug("failed to find resource with name {}, version {}. Status is {} ", name, version, status);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            return result;
+        }
+        return getToscaElementByOperation(getResourceRes.left().value().get(0));
+    }
 
-	// region - Component Update
-	public Either<ImmutablePair<Component, String>, StorageOperationStatus> addComponentInstanceToTopologyTemplate(Component containerComponent, Component origComponent, ComponentInstance componentInstance, boolean allowDeleted, User user) {
+    public Either<List<CatalogComponent>, StorageOperationStatus> getCatalogOrArchiveComponents(boolean isCatalog, List<OriginTypeEnum> excludeTypes) {
+        List<ResourceTypeEnum> excludedResourceTypes = Optional.ofNullable(excludeTypes).orElse(Collections.emptyList()).stream().filter(type -> !type.equals(OriginTypeEnum.SERVICE)).map(type -> ResourceTypeEnum.getTypeByName(type.name()))
+                .collect(Collectors.toList());
+        return topologyTemplateOperation.getElementCatalogData(isCatalog, excludedResourceTypes);
+    }
 
-		Either<ImmutablePair<Component, String>, StorageOperationStatus> result = null;
-		Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
-		if (StringUtils.isEmpty(componentInstance.getIcon())) {
-			componentInstance.setIcon(origComponent.getIcon());
-		}
-		String nameToFindForCounter = componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy ? componentInstance.getSourceModelName() + PROXY_SUFFIX : origComponent.getName();
-		String nextComponentInstanceCounter = getNextComponentInstanceCounter(containerComponent, nameToFindForCounter);
-		Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addResult = nodeTemplateOperation.addComponentInstanceToTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent),
-				ModelConverter.convertToToscaElement(origComponent), nextComponentInstanceCounter, componentInstance, allowDeleted, user);
+    // endregion
+    public <T extends Component> Either<List<T>, StorageOperationStatus> getCatalogComponents(ComponentTypeEnum componentType, List<OriginTypeEnum> excludeTypes, boolean isHighestVersions) {
+        List<T> components = new ArrayList<>();
+        Either<List<ToscaElement>, StorageOperationStatus> catalogDataResult;
+        List<ToscaElement> toscaElements = new ArrayList<>();
+        List<ResourceTypeEnum> excludedResourceTypes = Optional.ofNullable(excludeTypes).orElse(Collections.emptyList()).stream().filter(type -> !type.equals(OriginTypeEnum.SERVICE)).map(type -> ResourceTypeEnum.getTypeByName(type.name()))
+                .collect(Collectors.toList());
 
-		if (addResult.isRight()) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the component instance {} to container component {}. ", componentInstance.getName(), containerComponent.getName());
-			result = Either.right(addResult.right().value());
-		}
-		if (result == null) {
-			updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponent.getUniqueId());
-			if (updateContainerComponentRes.isRight()) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with updated component instance {}. ", containerComponent.getName(), componentInstance.getName());
-				result = Either.right(updateContainerComponentRes.right().value());
-			}
-		}
-		if (result == null) {
-			Component updatedComponent = ModelConverter.convertFromToscaElement(updateContainerComponentRes.left().value());
-			String createdInstanceId = addResult.left().value().getRight();
-			CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "The component instance {} has been added to container component {}. ", createdInstanceId, updatedComponent.getName());
-			result = Either.left(new ImmutablePair<>(updatedComponent, createdInstanceId));
-		}
-		return result;
-	}
+        switch (componentType) {
+            case RESOURCE:
+                catalogDataResult = nodeTypeOperation.getElementCatalogData(ComponentTypeEnum.RESOURCE, excludedResourceTypes, isHighestVersions);
+                if (catalogDataResult.isRight()) {
+                    return Either.right(catalogDataResult.right().value());
+                }
+                toscaElements = catalogDataResult.left().value();
+                break;
+            case SERVICE:
+                if (excludeTypes != null && excludeTypes.contains(OriginTypeEnum.SERVICE)) {
+                    break;
+                }
+                catalogDataResult = topologyTemplateOperation.getElementCatalogData(ComponentTypeEnum.SERVICE, null, isHighestVersions);
+                if (catalogDataResult.isRight()) {
+                    return Either.right(catalogDataResult.right().value());
+                }
+                toscaElements = catalogDataResult.left().value();
+                break;
+            default:
+                log.debug(NOT_SUPPORTED_COMPONENT_TYPE, componentType);
+                return Either.right(StorageOperationStatus.BAD_REQUEST);
+        }
+        toscaElements.forEach(te -> {
+            T component = ModelConverter.convertFromToscaElement(te);
+            components.add(component);
+        });
+        return Either.left(components);
+    }
 
-	public StorageOperationStatus associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, Resource> resourcesInstancesMap, boolean allowDeleted) {
+    public Either<List<String>, StorageOperationStatus> deleteMarkedElements(ComponentTypeEnum componentType) {
+        Either<List<GraphVertex>, StorageOperationStatus> allComponentsMarkedForDeletion;
+        switch (componentType) {
+            case RESOURCE:
+                allComponentsMarkedForDeletion = nodeTypeOperation.getAllComponentsMarkedForDeletion(componentType);
+                break;
+            case SERVICE:
+            case PRODUCT:
+                allComponentsMarkedForDeletion = topologyTemplateOperation.getAllComponentsMarkedForDeletion(componentType);
+                break;
+            default:
+                log.debug(NOT_SUPPORTED_COMPONENT_TYPE, componentType);
+                return Either.right(StorageOperationStatus.BAD_REQUEST);
+        }
+        if (allComponentsMarkedForDeletion.isRight()) {
+            return Either.right(allComponentsMarkedForDeletion.right().value());
+        }
+        List<GraphVertex> allMarked = allComponentsMarkedForDeletion.left().value();
+        return Either.left(checkIfInUseAndDelete(allMarked));
+    }
 
-		StorageOperationStatus result = null;
-		CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Going to add component instances to component {}", containerComponent.getUniqueId());
+    private List<String> checkIfInUseAndDelete(List<GraphVertex> allMarked) {
+        final List<EdgeLabelEnum> forbiddenEdgeLabelEnums = Arrays.asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF, EdgeLabelEnum.ALLOTTED_OF);
+        List<String> deleted = new ArrayList<>();
 
-		Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(containerComponent.getUniqueId(), JsonParseFlagEnum.ParseAll);
-		if (metadataVertex.isRight()) {
-			TitanOperationStatus status = metadataVertex.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if (result == null) {
-			result = nodeTemplateOperation.associateComponentInstancesToComponent(containerComponent, resourcesInstancesMap, metadataVertex.left().value(), allowDeleted);
-		}
-		return result;
-	}
+        for (GraphVertex elementV : allMarked) {
+            boolean isAllowedToDelete = true;
 
-	public Either<ImmutablePair<Component, String>, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(Component containerComponent, Component origComponent, ComponentInstance componentInstance) {
+            for (EdgeLabelEnum edgeLabelEnum : forbiddenEdgeLabelEnums) {
+                Either<Edge, TitanOperationStatus> belongingEdgeByCriteria = titanDao.getBelongingEdgeByCriteria(elementV, edgeLabelEnum, null);
+                if (belongingEdgeByCriteria.isLeft()){
+                    log.debug("Marked element {} in use. don't delete it", elementV.getUniqueId());
+                    isAllowedToDelete = false;
+                    break;
+                }
+            }
 
-		Either<ImmutablePair<Component, String>, StorageOperationStatus> result = null;
+            if (isAllowedToDelete) {
+                Either<ToscaElement, StorageOperationStatus> deleteToscaElement = deleteToscaElement(elementV);
+                if (deleteToscaElement.isRight()) {
+                    log.debug("Failed to delete marked element UniqueID {}, Name {}, error {}", elementV.getUniqueId(), elementV.getMetadataProperties().get(GraphPropertyEnum.NAME), deleteToscaElement.right().value());
+                    continue;
+                }
+                deleted.add(elementV.getUniqueId());
+            }
+        }
+        return deleted;
+    }
 
-		CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update the metadata of the component instance {} belonging to container component {}. ", componentInstance.getName(), containerComponent.getName());
-		componentInstance.setIcon(origComponent.getIcon());
-		Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateResult = nodeTemplateOperation.updateComponentInstanceMetadataOfTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent),
-				ModelConverter.convertToToscaElement(origComponent), componentInstance);
-		if (updateResult.isRight()) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the metadata of the component instance {} belonging to container component {}. ", componentInstance.getName(), containerComponent.getName());
-			result = Either.right(updateResult.right().value());
-		}
-		if (result == null) {
-			Component updatedComponent = ModelConverter.convertFromToscaElement(updateResult.left().value().getLeft());
-			String createdInstanceId = updateResult.left().value().getRight();
-			CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "The metadata of the component instance {} has been updated to container component {}. ", createdInstanceId, updatedComponent.getName());
-			result = Either.left(new ImmutablePair<>(updatedComponent, createdInstanceId));
-		}
-		return result;
-	}
+    public Either<List<String>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
+        Either<List<GraphVertex>, StorageOperationStatus> allComponentsMarkedForDeletion;
+        switch (componentType) {
+            case RESOURCE:
+                allComponentsMarkedForDeletion = nodeTypeOperation.getAllComponentsMarkedForDeletion(componentType);
+                break;
+            case SERVICE:
+            case PRODUCT:
+                allComponentsMarkedForDeletion = topologyTemplateOperation.getAllComponentsMarkedForDeletion(componentType);
+                break;
+            default:
+                log.debug(NOT_SUPPORTED_COMPONENT_TYPE, componentType);
+                return Either.right(StorageOperationStatus.BAD_REQUEST);
+        }
+        if (allComponentsMarkedForDeletion.isRight()) {
+            return Either.right(allComponentsMarkedForDeletion.right().value());
+        }
+        return Either.left(allComponentsMarkedForDeletion.left().value().stream().map(GraphVertex::getUniqueId).collect(Collectors.toList()));
+    }
 
-	public Either<Component, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(Component containerComponent) {
-		return updateComponentInstanceMetadataOfTopologyTemplate(containerComponent, new ComponentParametersView());
-	}
+    // region - Component Update
+    public Either<ImmutablePair<Component, String>, StorageOperationStatus> addComponentInstanceToTopologyTemplate(Component containerComponent, Component origComponent, ComponentInstance componentInstance, boolean allowDeleted, User user) {
 
-	public Either<Component, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(Component containerComponent, ComponentParametersView filter) {
+        Either<ImmutablePair<Component, String>, StorageOperationStatus> result = null;
+        Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
+        if (StringUtils.isEmpty(componentInstance.getIcon())) {
+            componentInstance.setIcon(origComponent.getIcon());
+        }
+        String nameToFindForCounter = componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy ? componentInstance.getSourceModelName() + PROXY_SUFFIX : origComponent.getName();
+        String nextComponentInstanceCounter = getNextComponentInstanceCounter(containerComponent, nameToFindForCounter);
+        Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addResult = nodeTemplateOperation.addComponentInstanceToTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent),
+                ModelConverter.convertToToscaElement(origComponent), nextComponentInstanceCounter, componentInstance, allowDeleted, user);
 
-		Either<Component, StorageOperationStatus> result = null;
+        if (addResult.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the component instance {} to container component {}. ", componentInstance.getName(), containerComponent.getName());
+            result = Either.right(addResult.right().value());
+        }
+        if (result == null) {
+            updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponent.getUniqueId());
+            if (updateContainerComponentRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with updated component instance {}. ", containerComponent.getName(), componentInstance.getName());
+                result = Either.right(updateContainerComponentRes.right().value());
+            }
+        }
+        if (result == null) {
+            Component updatedComponent = ModelConverter.convertFromToscaElement(updateContainerComponentRes.left().value());
+            String createdInstanceId = addResult.left().value().getRight();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "The component instance {} has been added to container component {}. ", createdInstanceId, updatedComponent.getName());
+            result = Either.left(new ImmutablePair<>(updatedComponent, createdInstanceId));
+        }
+        return result;
+    }
 
-		CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update the metadata  belonging to container component {}. ", containerComponent.getName());
+    public StorageOperationStatus associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, Resource> resourcesInstancesMap, boolean allowDeleted) {
 
-		Either<TopologyTemplate, StorageOperationStatus> updateResult = nodeTemplateOperation.updateComponentInstanceMetadataOfTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent), filter);
-		if (updateResult.isRight()) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the metadata  belonging to container component {}. ", containerComponent.getName());
-			result = Either.right(updateResult.right().value());
-		}
-		if (result == null) {
-			Component updatedComponent = ModelConverter.convertFromToscaElement(updateResult.left().value());
-			CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "The metadata has been updated to container component {}. ", updatedComponent.getName());
-			result = Either.left(updatedComponent);
-		}
-		return result;
-	}
-	// endregion
+        StorageOperationStatus result = null;
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Going to add component instances to component {}", containerComponent.getUniqueId());
 
-	public Either<ImmutablePair<Component, String>, StorageOperationStatus> deleteComponentInstanceFromTopologyTemplate(Component containerComponent, String resourceInstanceId) {
+        Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(containerComponent.getUniqueId(), JsonParseFlagEnum.ParseAll);
+        if (metadataVertex.isRight()) {
+            TitanOperationStatus status = metadataVertex.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if (result == null) {
+            result = nodeTemplateOperation.associateComponentInstancesToComponent(containerComponent, resourcesInstancesMap, metadataVertex.left().value(), allowDeleted);
+        }
+        return result;
+    }
 
-		Either<ImmutablePair<Component, String>, StorageOperationStatus> result = null;
+    public Either<ImmutablePair<Component, String>, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(Component containerComponent, Component origComponent, ComponentInstance componentInstance) {
 
-		CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to delete the component instance {} belonging to container component {}. ", resourceInstanceId, containerComponent.getName());
+        Either<ImmutablePair<Component, String>, StorageOperationStatus> result = null;
 
-		Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateResult = nodeTemplateOperation.deleteComponentInstanceFromTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent), resourceInstanceId);
-		if (updateResult.isRight()) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete the component instance {} belonging to container component {}. ", resourceInstanceId, containerComponent.getName());
-			result = Either.right(updateResult.right().value());
-		}
-		if (result == null) {
-			Component updatedComponent = ModelConverter.convertFromToscaElement(updateResult.left().value().getLeft());
-			String deletedInstanceId = updateResult.left().value().getRight();
-			CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "The component instance {} has been deleted from container component {}. ", deletedInstanceId, updatedComponent.getName());
-			result = Either.left(new ImmutablePair<>(updatedComponent, deletedInstanceId));
-		}
-		return result;
-	}
+        CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update the metadata of the component instance {} belonging to container component {}. ", componentInstance.getName(), containerComponent.getName());
+        componentInstance.setIcon(origComponent.getIcon());
+        Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateResult = nodeTemplateOperation.updateComponentInstanceMetadataOfTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent),
+                ModelConverter.convertToToscaElement(origComponent), componentInstance);
+        if (updateResult.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the metadata of the component instance {} belonging to container component {}. ", componentInstance.getName(), containerComponent.getName());
+            result = Either.right(updateResult.right().value());
+        }
+        if (result == null) {
+            Component updatedComponent = ModelConverter.convertFromToscaElement(updateResult.left().value().getLeft());
+            String createdInstanceId = updateResult.left().value().getRight();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "The metadata of the component instance {} has been updated to container component {}. ", createdInstanceId, updatedComponent.getName());
+            result = Either.left(new ImmutablePair<>(updatedComponent, createdInstanceId));
+        }
+        return result;
+    }
 
-	private String getNextComponentInstanceCounter(Component containerComponent, String originResourceName) {
+    public Either<Component, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(Component containerComponent) {
+        return updateComponentInstanceMetadataOfTopologyTemplate(containerComponent, new ComponentParametersView());
+    }
 
-		Integer nextCounter = 0;
+    public Either<Component, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(Component containerComponent, ComponentParametersView filter) {
 
-		if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstances())) {
+        Either<Component, StorageOperationStatus> result = null;
 
-			String normalizedName = ValidationUtils.normalizeComponentInstanceName(originResourceName);
-			Integer maxCounterFromNames = getMaxCounterFromNames(containerComponent, normalizedName);
-			Integer maxCounterFromIds = getMaxCounterFromIds(containerComponent, normalizedName);
+        CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update the metadata  belonging to container component {}. ", containerComponent.getName());
 
-			if (maxCounterFromNames == null && maxCounterFromIds != null) {
-				nextCounter = maxCounterFromIds + 1;
-			} else if (maxCounterFromIds == null && maxCounterFromNames != null) {
-				nextCounter = maxCounterFromNames + 1;
-			} else if (maxCounterFromIds != null && maxCounterFromNames != null) {
-				nextCounter = maxCounterFromNames > maxCounterFromIds ? maxCounterFromNames + 1 : maxCounterFromIds + 1;
-			}
-		}
-		return nextCounter.toString();
-	}
+        Either<TopologyTemplate, StorageOperationStatus> updateResult = nodeTemplateOperation.updateComponentInstanceMetadataOfTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent), filter);
+        if (updateResult.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the metadata  belonging to container component {}. ", containerComponent.getName());
+            result = Either.right(updateResult.right().value());
+        }
+        if (result == null) {
+            Component updatedComponent = ModelConverter.convertFromToscaElement(updateResult.left().value());
+            CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "The metadata has been updated to container component {}. ", updatedComponent.getName());
+            result = Either.left(updatedComponent);
+        }
+        return result;
+    }
+    // endregion
 
-	private Integer getMaxCounterFromNames(Component containerComponent, String normalizedName) {
+    public Either<ImmutablePair<Component, String>, StorageOperationStatus> deleteComponentInstanceFromTopologyTemplate(Component containerComponent, String resourceInstanceId) {
 
-		Integer maxCounter = 0;
-		List<String> countersStr = containerComponent.getComponentInstances().stream().filter(ci -> ci.getNormalizedName() != null && ci.getNormalizedName().startsWith(normalizedName)).map(ci -> ci.getNormalizedName().split(normalizedName)[1])
-				.collect(Collectors.toList());
+        Either<ImmutablePair<Component, String>, StorageOperationStatus> result = null;
 
-		if (CollectionUtils.isEmpty(countersStr)) {
-			return null;
-		}
-		Integer currCounter = null;
-		for (String counter : countersStr) {
-			if (StringUtils.isEmpty(counter)) {
-				continue;
-			}
-			try {
-				currCounter = Integer.parseInt(counter);
-			} catch (Exception e) {
-				continue;
-			}
-			maxCounter = maxCounter < currCounter ? currCounter : maxCounter;
-		}
-		if (currCounter == null) {
-			return null;
-		}
-		return maxCounter;
-	}
+        CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to delete the component instance {} belonging to container component {}. ", resourceInstanceId, containerComponent.getName());
 
-	private Integer getMaxCounterFromIds(Component containerComponent, String normalizedName) {
+        Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateResult = nodeTemplateOperation.deleteComponentInstanceFromTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent), resourceInstanceId);
+        if (updateResult.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete the component instance {} belonging to container component {}. ", resourceInstanceId, containerComponent.getName());
+            result = Either.right(updateResult.right().value());
+        }
+        if (result == null) {
+            Component updatedComponent = ModelConverter.convertFromToscaElement(updateResult.left().value().getLeft());
+            String deletedInstanceId = updateResult.left().value().getRight();
+            CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "The component instance {} has been deleted from container component {}. ", deletedInstanceId, updatedComponent.getName());
+            result = Either.left(new ImmutablePair<>(updatedComponent, deletedInstanceId));
+        }
+        return result;
+    }
 
-		Integer maxCounter = 0;
-		List<String> countersStr = containerComponent.getComponentInstances().stream().filter(ci -> ci.getUniqueId() != null && ci.getUniqueId().contains(normalizedName)).map(ci -> ci.getUniqueId().split(normalizedName)[1])
-				.collect(Collectors.toList());
+    private String getNextComponentInstanceCounter(Component containerComponent, String originResourceName) {
+        Integer nextCounter = 0;
+        if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstances())) {
+            String normalizedName = ValidationUtils.normalizeComponentInstanceName(originResourceName);
+            Integer maxCounter = getMaxCounterFromNamesAndIds(containerComponent, normalizedName);
+            if (maxCounter != null) {
+                nextCounter = maxCounter + 1;
+            }
+        }
+        return nextCounter.toString();
+    }
 
-		if (CollectionUtils.isEmpty(countersStr)) {
-			return null;
-		}
-		Integer currCounter = null;
-		for (String counter : countersStr) {
-			if (StringUtils.isEmpty(counter)) {
-				continue;
-			}
-			try {
-				currCounter = Integer.parseInt(counter);
-			} catch (Exception e) {
-				continue;
-			}
-			maxCounter = maxCounter < currCounter ? currCounter : maxCounter;
-		}
-		if (currCounter == null) {
-			return null;
-		}
-		return maxCounter;
-	}
+    /**
+     * @return max counter of component instance Id's, null if not found
+     */
+    private Integer getMaxCounterFromNamesAndIds(Component containerComponent, String normalizedName) {
+        List<String> countersInNames = containerComponent.getComponentInstances().stream()
+                .filter(ci -> ci.getNormalizedName() != null && ci.getNormalizedName().startsWith(normalizedName))
+                .map(ci -> ci.getNormalizedName().split(normalizedName)[1])
+                .collect(Collectors.toList());
+        List<String> countersInIds = containerComponent.getComponentInstances().stream()
+                .filter(ci -> ci.getUniqueId() != null && ci.getUniqueId().contains(normalizedName))
+                .map(ci -> ci.getUniqueId().split(normalizedName)[1])
+                .collect(Collectors.toList());
+        List<String> namesAndIdsList = new ArrayList<>(countersInNames);
+        namesAndIdsList.addAll(countersInIds);
+        return getMaxInteger(namesAndIdsList);
+    }
 
-	public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String componentId, RequirementCapabilityRelDef requirementDef) {
-		return nodeTemplateOperation.associateResourceInstances(componentId, requirementDef);
+    private Integer getMaxInteger(List<String> counters) {
+        Integer maxCounter = 0;
+        Integer currCounter = null;
+        for (String counter : counters) {
+            try {
+                currCounter = Integer.parseInt(counter);
+                if (maxCounter < currCounter) {
+                    maxCounter = currCounter;
+                }
+            } catch (NumberFormatException e) {
+                continue;
+            }
+        }
+        return currCounter == null ? null : maxCounter;
+    }
 
-	}
+    public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String componentId, RequirementCapabilityRelDef requirementDef) {
+        return nodeTemplateOperation.associateResourceInstances(componentId, requirementDef);
 
-	public Either<List<InputDefinition>, StorageOperationStatus> createAndAssociateInputs(Map<String, InputDefinition> inputs, String componentId) {
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+    public Either<List<InputDefinition>, StorageOperationStatus> createAndAssociateInputs(Map<String, InputDefinition> inputs, String componentId) {
 
-		}
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
 
-		GraphVertex vertex = getVertexEither.left().value();
-		Map<String, PropertyDataDefinition> inputsMap = inputs.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new PropertyDataDefinition(e.getValue())));
+        }
 
-		StorageOperationStatus status = topologyTemplateOperation.associateInputsToComponent(vertex, inputsMap, componentId);
+        GraphVertex vertex = getVertexEither.left().value();
+        Map<String, PropertyDataDefinition> inputsMap = inputs.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new PropertyDataDefinition(e.getValue())));
 
-		if (StorageOperationStatus.OK == status) {
-			log.debug("Component created successfully!!!");
-			List<InputDefinition> inputsResList = null;
-			if (inputsMap != null && !inputsMap.isEmpty()) {
-				inputsResList = inputsMap.values().stream().map(i -> new InputDefinition(i)).collect(Collectors.toList());
-			}
-			return Either.left(inputsResList);
-		}
-		return Either.right(status);
+        StorageOperationStatus status = topologyTemplateOperation.associateInputsToComponent(vertex, inputsMap, componentId);
 
-	}
+        if (StorageOperationStatus.OK == status) {
+            log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+            List<InputDefinition> inputsResList = null;
+            if (inputsMap != null && !inputsMap.isEmpty()) {
+                inputsResList = inputsMap.values().stream()
+                        .map(InputDefinition::new)
+                        .collect(Collectors.toList());
+            }
+            return Either.left(inputsResList);
+        }
+        return Either.right(status);
 
-	public Either<List<InputDefinition>, StorageOperationStatus> addInputsToComponent(Map<String, InputDefinition> inputs, String componentId) {
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+    public Either<List<InputDefinition>, StorageOperationStatus> addInputsToComponent(Map<String, InputDefinition> inputs, String componentId) {
 
-		}
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
 
-		GraphVertex vertex = getVertexEither.left().value();
-		Map<String, PropertyDataDefinition> inputsMap = inputs.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new PropertyDataDefinition(e.getValue())));
+        }
 
-		StorageOperationStatus status = topologyTemplateOperation.addToscaDataToToscaElement(vertex, EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputsMap, JsonPresentationFields.NAME);
+        GraphVertex vertex = getVertexEither.left().value();
+        Map<String, PropertyDataDefinition> inputsMap = inputs.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new PropertyDataDefinition(e.getValue())));
 
-		if (StorageOperationStatus.OK == status) {
-			log.debug("Component created successfully!!!");
-			List<InputDefinition> inputsResList = null;
-			if (inputsMap != null && !inputsMap.isEmpty()) {
-				inputsResList = inputsMap.values().stream().map(i -> new InputDefinition(i)).collect(Collectors.toList());
-			}
-			return Either.left(inputsResList);
-		}
-		return Either.right(status);
+        StorageOperationStatus status = topologyTemplateOperation.addToscaDataToToscaElement(vertex, EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputsMap, JsonPresentationFields.NAME);
 
-	}
+        if (StorageOperationStatus.OK == status) {
+            log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+            List<InputDefinition> inputsResList = null;
+            if (inputsMap != null && !inputsMap.isEmpty()) {
+                inputsResList = inputsMap.values().stream().map(InputDefinition::new).collect(Collectors.toList());
+            }
+            return Either.left(inputsResList);
+        }
+        return Either.right(status);
 
-	public Either<List<InputDefinition>, StorageOperationStatus> updateInputsToComponent(List<InputDefinition> inputs, String componentId) {
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+    public Either<List<InputDefinition>, StorageOperationStatus> updateInputsToComponent(List<InputDefinition> inputs, String componentId) {
 
-		}
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
 
-		GraphVertex vertex = getVertexEither.left().value();
-		List<PropertyDataDefinition> inputsAsDataDef = inputs.stream().map(PropertyDataDefinition::new).collect(Collectors.toList());
+        }
 
-		StorageOperationStatus status = topologyTemplateOperation.updateToscaDataOfToscaElement(vertex, EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputsAsDataDef, JsonPresentationFields.NAME);
+        GraphVertex vertex = getVertexEither.left().value();
+        List<PropertyDataDefinition> inputsAsDataDef = inputs.stream().map(PropertyDataDefinition::new).collect(Collectors.toList());
 
-		if (StorageOperationStatus.OK == status) {
-			log.debug("Component created successfully!!!");
-			List<InputDefinition> inputsResList = null;
-			if (inputsAsDataDef != null && !inputsAsDataDef.isEmpty()) {
-				inputsResList = inputsAsDataDef.stream().map(InputDefinition::new).collect(Collectors.toList());
-			}
-			return Either.left(inputsResList);
-		}
-		return Either.right(status);
+        StorageOperationStatus status = topologyTemplateOperation.updateToscaDataOfToscaElement(vertex, EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputsAsDataDef, JsonPresentationFields.NAME);
 
-	}
+        if (StorageOperationStatus.OK == status) {
+            log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+            List<InputDefinition> inputsResList = null;
+            if (inputsAsDataDef != null && !inputsAsDataDef.isEmpty()) {
+                inputsResList = inputsAsDataDef.stream().map(InputDefinition::new).collect(Collectors.toList());
+            }
+            return Either.left(inputsResList);
+        }
+        return Either.right(status);
 
-	// region - ComponentInstance
-	public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> associateComponentInstancePropertiesToComponent(Map<String, List<ComponentInstanceProperty>> instProperties, String componentId) {
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+    // region - ComponentInstance
+    public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> associateComponentInstancePropertiesToComponent(Map<String, List<ComponentInstanceProperty>> instProperties, String componentId) {
 
-		}
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
 
-		GraphVertex vertex = getVertexEither.left().value();
-		Map<String, MapPropertiesDataDefinition> instPropsMap = new HashMap<>();
-		if (instProperties != null) {
+        }
 
-			MapPropertiesDataDefinition propertiesMap;
-			for (Entry<String, List<ComponentInstanceProperty>> entry : instProperties.entrySet()) {
-				propertiesMap = new MapPropertiesDataDefinition();
+        GraphVertex vertex = getVertexEither.left().value();
+        Map<String, MapPropertiesDataDefinition> instPropsMap = new HashMap<>();
+        if (instProperties != null) {
 
-				propertiesMap.setMapToscaDataDefinition(entry.getValue().stream().map(e -> new PropertyDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
+            MapPropertiesDataDefinition propertiesMap;
+            for (Entry<String, List<ComponentInstanceProperty>> entry : instProperties.entrySet()) {
+                propertiesMap = new MapPropertiesDataDefinition();
 
-				instPropsMap.put(entry.getKey(), propertiesMap);
-			}
-		}
+                propertiesMap.setMapToscaDataDefinition(entry.getValue().stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, e -> e)));
 
-		StorageOperationStatus status = topologyTemplateOperation.associateInstPropertiesToComponent(vertex, instPropsMap);
+                instPropsMap.put(entry.getKey(), propertiesMap);
+            }
+        }
 
-		if (StorageOperationStatus.OK == status) {
-			log.debug("Component created successfully!!!");
-			return Either.left(instProperties);
-		}
-		return Either.right(status);
+        StorageOperationStatus status = topologyTemplateOperation.associateInstPropertiesToComponent(vertex, instPropsMap);
 
-	}
+        if (StorageOperationStatus.OK == status) {
+            log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+            return Either.left(instProperties);
+        }
+        return Either.right(status);
 
-	/**
-	 * saves the instInputs as the updated instance inputs of the component container in DB
-	 * @param instInputs
-	 * @param componentId
-	 * @return
-	 */
-	public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> updateComponentInstanceInputsToComponent(Map<String, List<ComponentInstanceInput>> instInputs, String componentId) {
-		if (instInputs == null || instInputs.isEmpty()) {
-			return Either.left(instInputs);
-		}
-		StorageOperationStatus status;
-		for ( Entry<String, List<ComponentInstanceInput>> inputsPerIntance : instInputs.entrySet() ) {
-			List<ComponentInstanceInput> toscaDataListPerInst = inputsPerIntance.getValue();
-			List<String> pathKeysPerInst = new ArrayList<>();
-			pathKeysPerInst.add(inputsPerIntance.getKey());
-			status = topologyTemplateOperation.updateToscaDataDeepElementsOfToscaElement(componentId, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, toscaDataListPerInst, pathKeysPerInst, JsonPresentationFields.NAME);
-			if ( status != StorageOperationStatus.OK) {
-				log.debug("Failed to update component instance inputs for instance {} in component {} edge type {} error {}", inputsPerIntance.getKey(), componentId,  EdgeLabelEnum.INST_INPUTS, status);
-				return Either.right(status);
-			}
-		}
+    }
 
-		return Either.left(instInputs);
-	}
+    /**
+     * saves the instInputs as the updated instance inputs of the component container in DB
+     */
+    public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> updateComponentInstanceInputsToComponent(Map<String, List<ComponentInstanceInput>> instInputs, String componentId) {
+        if (instInputs == null || instInputs.isEmpty()) {
+            return Either.left(instInputs);
+        }
+        StorageOperationStatus status;
+        for (Entry<String, List<ComponentInstanceInput>> inputsPerIntance : instInputs.entrySet()) {
+            List<ComponentInstanceInput> toscaDataListPerInst = inputsPerIntance.getValue();
+            List<String> pathKeysPerInst = new ArrayList<>();
+            pathKeysPerInst.add(inputsPerIntance.getKey());
+            status = topologyTemplateOperation.updateToscaDataDeepElementsOfToscaElement(componentId, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, toscaDataListPerInst, pathKeysPerInst, JsonPresentationFields.NAME);
+            if (status != StorageOperationStatus.OK) {
+                log.debug("Failed to update component instance inputs for instance {} in component {} edge type {} error {}", inputsPerIntance.getKey(), componentId, EdgeLabelEnum.INST_INPUTS, status);
+                return Either.right(status);
+            }
+        }
 
-	/**
-	 * saves the instProps as the updated instance properties of the component container in DB
-	 * @param instProps
-	 * @param componentId
-	 * @return
-	 */
-	public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> updateComponentInstancePropsToComponent(Map<String, List<ComponentInstanceProperty>> instProps, String componentId) {
-		if (instProps == null || instProps.isEmpty()) {
-			return Either.left(instProps);
-		}
-		StorageOperationStatus status;
-		for ( Entry<String, List<ComponentInstanceProperty>> propsPerIntance : instProps.entrySet() ) {
-			List<ComponentInstanceProperty> toscaDataListPerInst = propsPerIntance.getValue();
-			List<String> pathKeysPerInst = new ArrayList<>();
-			pathKeysPerInst.add(propsPerIntance.getKey());
-			status = topologyTemplateOperation.updateToscaDataDeepElementsOfToscaElement(componentId, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, toscaDataListPerInst, pathKeysPerInst, JsonPresentationFields.NAME);
-			if ( status != StorageOperationStatus.OK) {
-				log.debug("Failed to update component instance inputs for instance {} in component {} edge type {} error {}", propsPerIntance.getKey(), componentId,  EdgeLabelEnum.INST_PROPERTIES, status);
-				return Either.right(status);
-			}
-		}
+        return Either.left(instInputs);
+    }
 
-		return Either.left(instProps);
-	}
+    /**
+     * saves the instProps as the updated instance properties of the component container in DB
+     */
+    public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> updateComponentInstancePropsToComponent(Map<String, List<ComponentInstanceProperty>> instProps, String componentId) {
+        if (instProps == null || instProps.isEmpty()) {
+            return Either.left(instProps);
+        }
+        StorageOperationStatus status;
+        for (Entry<String, List<ComponentInstanceProperty>> propsPerIntance : instProps.entrySet()) {
+            List<ComponentInstanceProperty> toscaDataListPerInst = propsPerIntance.getValue();
+            List<String> pathKeysPerInst = new ArrayList<>();
+            pathKeysPerInst.add(propsPerIntance.getKey());
+            status = topologyTemplateOperation.updateToscaDataDeepElementsOfToscaElement(componentId, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, toscaDataListPerInst, pathKeysPerInst, JsonPresentationFields.NAME);
+            if (status != StorageOperationStatus.OK) {
+                log.debug("Failed to update component instance inputs for instance {} in component {} edge type {} error {}", propsPerIntance.getKey(), componentId, EdgeLabelEnum.INST_PROPERTIES, status);
+                return Either.right(status);
+            }
+        }
 
-	public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> associateComponentInstanceInputsToComponent(Map<String, List<ComponentInstanceInput>> instInputs, String componentId) {
+        return Either.left(instProps);
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+    public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> associateComponentInstanceInputsToComponent(Map<String, List<ComponentInstanceInput>> instInputs, String componentId) {
 
-		}
-		GraphVertex vertex = getVertexEither.left().value();
-		Map<String, MapPropertiesDataDefinition> instPropsMap = new HashMap<>();
-		if (instInputs != null) {
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
 
-			MapPropertiesDataDefinition propertiesMap;
-			for (Entry<String, List<ComponentInstanceInput>> entry : instInputs.entrySet()) {
-				propertiesMap = new MapPropertiesDataDefinition();
+        }
+        GraphVertex vertex = getVertexEither.left().value();
+        Map<String, MapPropertiesDataDefinition> instPropsMap = new HashMap<>();
+        if (instInputs != null) {
 
-				propertiesMap.setMapToscaDataDefinition(entry.getValue().stream().map(e -> new PropertyDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
+            MapPropertiesDataDefinition propertiesMap;
+            for (Entry<String, List<ComponentInstanceInput>> entry : instInputs.entrySet()) {
+                propertiesMap = new MapPropertiesDataDefinition();
 
-				instPropsMap.put(entry.getKey(), propertiesMap);
-			}
-		}
+                propertiesMap.setMapToscaDataDefinition(entry.getValue().stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, e -> e)));
 
-		StorageOperationStatus status = topologyTemplateOperation.associateInstInputsToComponent(vertex, instPropsMap);
+                instPropsMap.put(entry.getKey(), propertiesMap);
+            }
+        }
 
-		if (StorageOperationStatus.OK == status) {
-			log.debug("Component created successfully!!!");
-			return Either.left(instInputs);
-		}
-		return Either.right(status);
+        StorageOperationStatus status = topologyTemplateOperation.associateInstInputsToComponent(vertex, instPropsMap);
 
-	}
+        if (StorageOperationStatus.OK == status) {
+            log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+            return Either.left(instInputs);
+        }
+        return Either.right(status);
 
-	public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> addComponentInstanceInputsToComponent(Component containerComponent, Map<String, List<ComponentInstanceInput>> instProperties) {
+    }
 
-		StorageOperationStatus status = StorageOperationStatus.OK;
-		if (instProperties != null) {
+    public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> addComponentInstanceInputsToComponent(Component containerComponent, Map<String, List<ComponentInstanceInput>> instProperties) {
+        requireNonNull(instProperties);
+        StorageOperationStatus status;
+        for (Entry<String, List<ComponentInstanceInput>> entry : instProperties.entrySet()) {
+            List<ComponentInstanceInput> props = entry.getValue();
+            String componentInstanceId = entry.getKey();
+            if (!isEmpty(props)) {
+                for (ComponentInstanceInput property : props) {
+                    List<ComponentInstanceInput> componentInstancesInputs = containerComponent.getComponentInstancesInputs().get(componentInstanceId);
+                    Optional<ComponentInstanceInput> instanceProperty = componentInstancesInputs.stream()
+                            .filter(p -> p.getName().equals(property.getName()))
+                            .findAny();
+                    if (instanceProperty.isPresent()) {
+                        status = updateComponentInstanceInput(containerComponent, componentInstanceId, property);
+                    } else {
+                        status = addComponentInstanceInput(containerComponent, componentInstanceId, property);
+                    }
+                    if (status != StorageOperationStatus.OK) {
+                        log.debug("Failed to update instance input {} for instance {} error {} ", property, componentInstanceId, status);
+                        return Either.right(status);
+                    } else {
+                        log.trace("instance input {} for instance {} updated", property, componentInstanceId);
+                    }
+                }
+            }
+        }
+        return Either.left(instProperties);
+    }
+    
+    public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addComponentInstancePropertiesToComponent(Component containerComponent, Map<String, List<ComponentInstanceProperty>> instProperties) {
+        requireNonNull(instProperties);
+        StorageOperationStatus status;
+        for (Entry<String, List<ComponentInstanceProperty>> entry : instProperties.entrySet()) {
+            List<ComponentInstanceProperty> props = entry.getValue();
+            String componentInstanceId = entry.getKey();
+            List<ComponentInstanceProperty> instanceProperties = containerComponent.getComponentInstancesProperties().get(componentInstanceId);
+            if (!isEmpty(props)) {
+                for (ComponentInstanceProperty property : props) {
+                    Optional<ComponentInstanceProperty> instanceProperty = instanceProperties.stream()
+                            .filter(p -> p.getUniqueId().equals(property.getUniqueId()))
+                            .findAny();
+                    if (instanceProperty.isPresent()) {
+                        status = updateComponentInstanceProperty(containerComponent, componentInstanceId, property);
+                    } else {
+                        status = addComponentInstanceProperty(containerComponent, componentInstanceId, property);
+                    }
+                    if (status != StorageOperationStatus.OK) {
+                        log.debug("Failed to update instance property {} for instance {} error {} ", property, componentInstanceId, status);
+                        return Either.right(status);
+                    }
+                }
+            }
+        }
+        return Either.left(instProperties);
+    }
 
-			for (Entry<String, List<ComponentInstanceInput>> entry : instProperties.entrySet()) {
-				List<ComponentInstanceInput> props = entry.getValue();
-				String componentInstanseId = entry.getKey();
-				if (props != null && !props.isEmpty()) {
-					for (ComponentInstanceInput property : props) {
-						List<ComponentInstanceInput> componentInstancesInputs = containerComponent.getComponentInstancesInputs().get(componentInstanseId);
-						Optional<ComponentInstanceInput> instanceProperty = componentInstancesInputs.stream().filter(p -> p.getName().equals(property.getName())).findAny();
-						if (instanceProperty.isPresent()) {
-							status = updateComponentInstanceInput(containerComponent, componentInstanseId, property);
-						} else {
-							status = addComponentInstanceInput(containerComponent, componentInstanseId, property);
-						}
-						if (status != StorageOperationStatus.OK) {
-							log.debug("Failed to update instance input {} for instance {} error {} ", property, componentInstanseId, status);
-							return Either.right(status);
-						} else {
-							log.trace("instance input {} for instance {} updated", property, componentInstanseId);
-						}
-					}
-				}
-			}
-		}
-		return Either.left(instProperties);
-	}
+    public StorageOperationStatus associateDeploymentArtifactsToInstances(Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts, String componentId, User user) {
 
-	public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addComponentInstancePropertiesToComponent(Component containerComponent, Map<String, List<ComponentInstanceProperty>> instProperties, String componentId) {
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value());
 
-		if (instProperties != null) {
+        }
 
-			for (Entry<String, List<ComponentInstanceProperty>> entry : instProperties.entrySet()) {
-				List<ComponentInstanceProperty> props = entry.getValue();
-				String componentInstanseId = entry.getKey();
-				List<ComponentInstanceProperty> instanceProperties = containerComponent.getComponentInstancesProperties().get(componentInstanseId);
-				if (props != null && !props.isEmpty()) {
-					for (ComponentInstanceProperty property : props) {
-						Optional<ComponentInstanceProperty> instanceProperty = instanceProperties.stream().filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny();
-						if (instanceProperty.isPresent()) {
-							updateComponentInstanceProperty(containerComponent, componentInstanseId, property);
-						} else {
-							addComponentInstanceProperty(containerComponent, componentInstanseId, property);
-						}
+        GraphVertex vertex = getVertexEither.left().value();
+        Map<String, MapArtifactDataDefinition> instArtMap = new HashMap<>();
+        if (instDeploymentArtifacts != null) {
 
-					}
-				}
-			}
-		}
+            MapArtifactDataDefinition artifactsMap;
+            for (Entry<String, Map<String, ArtifactDefinition>> entry : instDeploymentArtifacts.entrySet()) {
+                Map<String, ArtifactDefinition> artList = entry.getValue();
+                Map<String, ArtifactDataDefinition> artifacts = artList.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
+                artifactsMap = nodeTemplateOperation.prepareInstDeploymentArtifactPerInstance(artifacts, entry.getKey(), user, NodeTemplateOperation.HEAT_VF_ENV_NAME);
 
-		return Either.left(instProperties);
+                instArtMap.put(entry.getKey(), artifactsMap);
+            }
+        }
 
-	}
+        return topologyTemplateOperation.associateInstDeploymentArtifactsToComponent(vertex, instArtMap);
 
-	public StorageOperationStatus associateDeploymentArtifactsToInstances(Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts, String componentId, User user) {
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value());
+    public StorageOperationStatus associateArtifactsToInstances(Map<String, Map<String, ArtifactDefinition>> instArtifacts, String componentId) {
 
-		}
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value());
 
-		GraphVertex vertex = getVertexEither.left().value();
-		Map<String, MapArtifactDataDefinition> instArtMap = new HashMap<>();
-		if (instDeploymentArtifacts != null) {
+        }
 
-			MapArtifactDataDefinition artifactsMap;
-			for (Entry<String, Map<String, ArtifactDefinition>> entry : instDeploymentArtifacts.entrySet()) {
-				Map<String, ArtifactDefinition> artList = entry.getValue();
-				Map<String, ArtifactDataDefinition> artifacts = artList.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
-				artifactsMap = nodeTemplateOperation.prepareInstDeploymentArtifactPerInstance(artifacts, entry.getKey(), user, NodeTemplateOperation.HEAT_VF_ENV_NAME);
+        GraphVertex vertex = getVertexEither.left().value();
+        Map<String, MapArtifactDataDefinition> instArtMap = new HashMap<>();
+        if (instArtifacts != null) {
 
-				instArtMap.put(entry.getKey(), artifactsMap);
-			}
-		}
+            MapArtifactDataDefinition artifactsMap;
+            for (Entry<String, Map<String, ArtifactDefinition>> entry : instArtifacts.entrySet()) {
+                Map<String, ArtifactDefinition> artList = entry.getValue();
+                Map<String, ArtifactDataDefinition> artifacts = artList.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
+                artifactsMap = new MapArtifactDataDefinition(artifacts);
 
-		return topologyTemplateOperation.associateInstDeploymentArtifactsToComponent(vertex, instArtMap);
+                instArtMap.put(entry.getKey(), artifactsMap);
+            }
+        }
 
-	}
+        return topologyTemplateOperation.associateInstArtifactsToComponent(vertex, instArtMap);
 
-	public StorageOperationStatus associateArtifactsToInstances(Map<String, Map<String, ArtifactDefinition>> instArtifacts, String componentId, User user) {
+    }
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value());
+    public StorageOperationStatus associateInstAttributeToComponentToInstances(Map<String, List<PropertyDefinition>> instArttributes, String componentId) {
 
-		}
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value());
 
-		GraphVertex vertex = getVertexEither.left().value();
-		Map<String, MapArtifactDataDefinition> instArtMap = new HashMap<>();
-		if (instArtifacts != null) {
+        }
 
-			MapArtifactDataDefinition artifactsMap;
-			for (Entry<String, Map<String, ArtifactDefinition>> entry : instArtifacts.entrySet()) {
-				Map<String, ArtifactDefinition> artList = entry.getValue();
-				Map<String, ArtifactDataDefinition> artifacts = artList.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
-				artifactsMap = new MapArtifactDataDefinition(artifacts);
+        GraphVertex vertex = getVertexEither.left().value();
+        Map<String, MapPropertiesDataDefinition> instAttr = new HashMap<>();
+        if (instArttributes != null) {
 
-				instArtMap.put(entry.getKey(), artifactsMap);
-			}
-		}
+            MapPropertiesDataDefinition attributesMap;
+            for (Entry<String, List<PropertyDefinition>> entry : instArttributes.entrySet()) {
+                attributesMap = new MapPropertiesDataDefinition();
+                attributesMap.setMapToscaDataDefinition(entry.getValue().stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, e -> e)));
+                instAttr.put(entry.getKey(), attributesMap);
+            }
+        }
 
-		return topologyTemplateOperation.associateInstArtifactsToComponent(vertex, instArtMap);
+        return topologyTemplateOperation.associateInstAttributeToComponent(vertex, instAttr);
 
-	}
+    }
+    // endregion
 
-	public StorageOperationStatus associateInstAttributeToComponentToInstances(Map<String, List<PropertyDefinition>> instArttributes, String componentId) {
+    public StorageOperationStatus associateOrAddCalculatedCapReq(Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties, Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instReg, String componentId) {
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value());
 
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value());
+        }
 
-		}
+        GraphVertex vertex = getVertexEither.left().value();
 
-		GraphVertex vertex = getVertexEither.left().value();
-		Map<String, MapPropertiesDataDefinition> instAttr = new HashMap<>();
-		if (instArttributes != null) {
+        Map<String, MapListRequirementDataDefinition> calcRequirements = new HashMap<>();
 
-			MapPropertiesDataDefinition attributesMap;
-			for (Entry<String, List<PropertyDefinition>> entry : instArttributes.entrySet()) {
-				attributesMap = new MapPropertiesDataDefinition();
-				attributesMap.setMapToscaDataDefinition(entry.getValue().stream().map(e -> new PropertyDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
-				instAttr.put(entry.getKey(), attributesMap);
-			}
-		}
+        Map<String, MapListCapabilityDataDefinition> calcCapabilty = new HashMap<>();
+        Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties = new HashMap<>();
+        if (instCapabilties != null) {
+            for (Entry<ComponentInstance, Map<String, List<CapabilityDefinition>>> entry : instCapabilties.entrySet()) {
 
-		return topologyTemplateOperation.associateInstAttributeToComponent(vertex, instAttr);
+                Map<String, List<CapabilityDefinition>> caps = entry.getValue();
+                Map<String, ListCapabilityDataDefinition> mapToscaDataDefinition = new HashMap<>();
+                for (Entry<String, List<CapabilityDefinition>> instCapability : caps.entrySet()) {
+                    mapToscaDataDefinition.put(instCapability.getKey(), new ListCapabilityDataDefinition(instCapability.getValue().stream().map(CapabilityDataDefinition::new).collect(Collectors.toList())));
+                }
 
-	}
-	// endregion
+                ComponentInstanceDataDefinition componentInstance = new ComponentInstanceDataDefinition(entry.getKey());
+                MapListCapabilityDataDefinition capMap = nodeTemplateOperation.prepareCalculatedCapabiltyForNodeType(mapToscaDataDefinition, componentInstance);
 
-	public StorageOperationStatus associateCalculatedCapReq(Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties, Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instReg, String componentId) {
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value());
+                MapCapabilityProperty MapCapabilityProperty = ModelConverter.convertToMapOfMapCapabiltyProperties(caps, componentInstance.getUniqueId(), true);
 
-		}
+                calcCapabilty.put(entry.getKey().getUniqueId(), capMap);
+                calculatedCapabilitiesProperties.put(entry.getKey().getUniqueId(), MapCapabilityProperty);
+            }
+        }
 
-		GraphVertex vertex = getVertexEither.left().value();
+        if (instReg != null) {
+            for (Entry<ComponentInstance, Map<String, List<RequirementDefinition>>> entry : instReg.entrySet()) {
 
-		Map<String, MapListRequirementDataDefinition> calcRequirements = new HashMap<>();
+                Map<String, List<RequirementDefinition>> req = entry.getValue();
+                Map<String, ListRequirementDataDefinition> mapToscaDataDefinition = new HashMap<>();
+                for (Entry<String, List<RequirementDefinition>> instReq : req.entrySet()) {
+                    mapToscaDataDefinition.put(instReq.getKey(), new ListRequirementDataDefinition(instReq.getValue().stream().map(RequirementDataDefinition::new).collect(Collectors.toList())));
+                }
 
-		Map<String, MapListCapabiltyDataDefinition> calcCapabilty = new HashMap<>();
-		Map<String, MapCapabiltyProperty> calculatedCapabilitiesProperties = new HashMap<>();
-		;
-		if (instCapabilties != null) {
-			for (Entry<ComponentInstance, Map<String, List<CapabilityDefinition>>> entry : instCapabilties.entrySet()) {
+                MapListRequirementDataDefinition capMap = nodeTemplateOperation.prepareCalculatedRequirementForNodeType(mapToscaDataDefinition, new ComponentInstanceDataDefinition(entry.getKey()));
 
-				Map<String, List<CapabilityDefinition>> caps = entry.getValue();
-				Map<String, ListCapabilityDataDefinition> mapToscaDataDefinition = new HashMap<>();
-				for (Entry<String, List<CapabilityDefinition>> instCapability : caps.entrySet()) {
-					mapToscaDataDefinition.put(instCapability.getKey(), new ListCapabilityDataDefinition(instCapability.getValue().stream().map(iCap -> new CapabilityDataDefinition(iCap)).collect(Collectors.toList())));
-				}
+                calcRequirements.put(entry.getKey().getUniqueId(), capMap);
+            }
+        }
 
-				ComponentInstanceDataDefinition componentInstance = new ComponentInstanceDataDefinition(entry.getKey());
-				MapListCapabiltyDataDefinition capMap = nodeTemplateOperation.prepareCalculatedCapabiltyForNodeType(mapToscaDataDefinition, componentInstance);
+        return topologyTemplateOperation.associateOrAddCalcCapReqToComponent(vertex, calcRequirements, calcCapabilty, calculatedCapabilitiesProperties);
+    }
 
-				MapCapabiltyProperty mapCapabiltyProperty = ModelConverter.convertToMapOfMapCapabiltyProperties(caps, componentInstance.getUniqueId(), true);
+    private Either<List<Service>, StorageOperationStatus> getLatestVersionNonCheckoutServicesMetadataOnly(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps) {
+        List<Service> services = new ArrayList<>();
+        List<LifecycleStateEnum> states = new ArrayList<>();
+        // include props
+        hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
+        hasProps.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
 
-				calcCapabilty.put(entry.getKey().getUniqueId(), capMap);
-				calculatedCapabilitiesProperties.put(entry.getKey().getUniqueId(), mapCapabiltyProperty);
-			}
-		}
+        // exclude props
+        states.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+        hasNotProps.put(GraphPropertyEnum.STATE, states);
+        hasNotProps.put(GraphPropertyEnum.IS_DELETED, true);
+        hasNotProps.put(GraphPropertyEnum.IS_ARCHIVED, true);
+        return fetchServicesByCriteria(services, hasProps, hasNotProps);
+    }
 
-		if (instReg != null) {
-			for (Entry<ComponentInstance, Map<String, List<RequirementDefinition>>> entry : instReg.entrySet()) {
+    private Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractToscaElementsMetadataOnly(boolean isAbstract, ComponentTypeEnum componentTypeEnum, String internalComponentType, VertexTypeEnum vertexType) {
+        List<Service> services = null;
+        Map<GraphPropertyEnum, Object> hasProps = new EnumMap<>(GraphPropertyEnum.class);
+        Map<GraphPropertyEnum, Object> hasNotProps = new EnumMap<>(GraphPropertyEnum.class);
+        fillPropsMap(hasProps, hasNotProps, internalComponentType, componentTypeEnum, isAbstract, vertexType);
+        Either<List<GraphVertex>, TitanOperationStatus> getRes = titanDao.getByCriteria(vertexType, hasProps, hasNotProps, JsonParseFlagEnum.ParseMetadata);
+        if (getRes.isRight()) {
+            if (getRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
+                return Either.left(new ArrayList<>());
+            } else {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getRes.right().value()));
+            }
+        }
+        // region -> Fetch non checked-out services
+        if (internalComponentType != null && internalComponentType.toLowerCase().trim().equals(SERVICE) && VertexTypeEnum.NODE_TYPE == vertexType) {
+            Either<List<Service>, StorageOperationStatus> result = getLatestVersionNonCheckoutServicesMetadataOnly(new EnumMap<>(GraphPropertyEnum.class), new EnumMap<>(GraphPropertyEnum.class));
+            if (result.isRight()) {
+                log.debug("Failed to fetch services for");
+                return Either.right(result.right().value());
+            }
+            services = result.left().value();
+            if (log.isTraceEnabled() && isEmpty(services))
+                log.trace("No relevant services available");
+        }
+        // endregion
+        List<Component> nonAbstractLatestComponents = new ArrayList<>();
+        ComponentParametersView params = new ComponentParametersView(true);
+        params.setIgnoreAllVersions(false);
+        for (GraphVertex vertexComponent : getRes.left().value()) {
+            Either<ToscaElement, StorageOperationStatus> componentRes = topologyTemplateOperation.getLightComponent(vertexComponent, componentTypeEnum, params);
+            if (componentRes.isRight()) {
+                log.debug("Failed to fetch light element for {} error {}", vertexComponent.getUniqueId(), componentRes.right().value());
+                return Either.right(componentRes.right().value());
+            } else {
+                Component component = ModelConverter.convertFromToscaElement(componentRes.left().value());
+                nonAbstractLatestComponents.add(component);
+            }
+        }
+        if (CollectionUtils.isNotEmpty(services)) {
+            nonAbstractLatestComponents.addAll(services);
+        }
+        return Either.left(nonAbstractLatestComponents);
+    }
 
-				Map<String, List<RequirementDefinition>> req = entry.getValue();
-				Map<String, ListRequirementDataDefinition> mapToscaDataDefinition = new HashMap<>();
-				for (Entry<String, List<RequirementDefinition>> instReq : req.entrySet()) {
-					mapToscaDataDefinition.put(instReq.getKey(), new ListRequirementDataDefinition(instReq.getValue().stream().map(iCap -> new RequirementDataDefinition(iCap)).collect(Collectors.toList())));
-				}
+    public Either<ComponentMetadataData, StorageOperationStatus> getLatestComponentMetadataByUuid(String componentUuid, JsonParseFlagEnum parseFlag, Boolean isHighest) {
 
-				MapListRequirementDataDefinition capMap = nodeTemplateOperation.prepareCalculatedRequirementForNodeType(mapToscaDataDefinition, new ComponentInstanceDataDefinition(entry.getKey()));
+        Either<ComponentMetadataData, StorageOperationStatus> result;
+        Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
+        hasProperties.put(GraphPropertyEnum.UUID, componentUuid);
+        if (isHighest != null) {
+            hasProperties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, isHighest);
+        }
+        Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+        propertiesNotToMatch.put(GraphPropertyEnum.IS_ARCHIVED, true); //US382674, US382683
 
-				calcRequirements.put(entry.getKey().getUniqueId(), capMap);
-			}
-		}
+        Either<List<GraphVertex>, TitanOperationStatus> getRes = titanDao.getByCriteria(null, hasProperties, propertiesNotToMatch, parseFlag);
+        if (getRes.isRight()) {
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getRes.right().value()));
+        } else {
+            List<ComponentMetadataData> latestVersionList = getRes.left().value().stream().map(ModelConverter::convertToComponentMetadata).collect(Collectors.toList());
+            ComponentMetadataData latestVersion = latestVersionList.size() == 1 ? latestVersionList.get(0)
+                    : latestVersionList.stream().max((c1, c2) -> Double.compare(Double.parseDouble(c1.getMetadataDataDefinition().getVersion()), Double.parseDouble(c2.getMetadataDataDefinition().getVersion()))).get();
+            result = Either.left(latestVersion);
+        }
+        return result;
+    }
 
-		StorageOperationStatus status = topologyTemplateOperation.associateCalcCapReqToComponent(vertex, calcRequirements, calcCapabilty, calculatedCapabilitiesProperties);
+    public Either<ComponentMetadataData, StorageOperationStatus> getComponentMetadata(String componentId) {
+        Either<ComponentMetadataData, StorageOperationStatus> result;
+        Either<GraphVertex, TitanOperationStatus> getRes = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
+        if (getRes.isRight()) {
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getRes.right().value()));
+        } else {
+            ComponentMetadataData componentMetadata = ModelConverter.convertToComponentMetadata(getRes.left().value());
+            result = Either.left(componentMetadata);
+        }
+        return result;
+    }
 
-		return status;
-	}
+    public Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractComponents(boolean isAbstract, ComponentTypeEnum componentTypeEnum,
+                                                                                                 String internalComponentType, List<String> componentUids) {
 
-	private Either<List<Service>, StorageOperationStatus> getLatestVersionNonCheckoutServicesMetadataOnly(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps) {
-		List<Service> services = new ArrayList<>();
-		List<LifecycleStateEnum> states = new ArrayList<>();
-		// include props
-		hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
-		hasProps.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        List<Component> components = new ArrayList<>();
+        if (componentUids == null) {
+            Either<List<String>, StorageOperationStatus> componentUidsRes = getComponentUids(isAbstract, componentTypeEnum, internalComponentType);
+            if (componentUidsRes.isRight()) {
+                return Either.right(componentUidsRes.right().value());
+            }
+            componentUids = componentUidsRes.left().value();
+        }
+        if (!isEmpty(componentUids)) {
+            for (String componentUid : componentUids) {
+                ComponentParametersView componentParametersView = buildComponentViewForNotAbstract();
+                if ("vl".equalsIgnoreCase(internalComponentType)) {
+                    componentParametersView.setIgnoreCapabilities(false);
+                    componentParametersView.setIgnoreRequirements(false);
+                }
+                Either<ToscaElement, StorageOperationStatus> getToscaElementRes = nodeTemplateOperation.getToscaElementOperation(componentTypeEnum).getLightComponent(componentUid, componentTypeEnum, componentParametersView);
+                if (getToscaElementRes.isRight()) {
+                    log.debug("Failed to fetch resource for error is {}", getToscaElementRes.right().value());
+                    return Either.right(getToscaElementRes.right().value());
+                }
+                Component component = ModelConverter.convertFromToscaElement(getToscaElementRes.left().value());
+                nullifySomeComponentProperties(component);
+                components.add(component);
+            }
+        }
+        return Either.left(components);
+    }
 
-		// exclude props
-		states.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
-		hasNotProps.put(GraphPropertyEnum.STATE, states);
-		hasNotProps.put(GraphPropertyEnum.IS_DELETED, true);
-		return fetchServicesByCriteria(services, hasProps, hasNotProps);
-	}
+    public void nullifySomeComponentProperties(Component component) {
+        component.setContactId(null);
+        component.setCreationDate(null);
+        component.setCreatorUserId(null);
+        component.setCreatorFullName(null);
+        component.setLastUpdateDate(null);
+        component.setLastUpdaterUserId(null);
+        component.setLastUpdaterFullName(null);
+        component.setNormalizedName(null);
+    }
 
-	private Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractToscaElementsMetadataOnly(boolean isAbstract, Boolean isHighest, ComponentTypeEnum componentTypeEnum, String internalComponentType, VertexTypeEnum vertexType) {
-		List<Service> services = null;
-		Map<GraphPropertyEnum, Object> hasProps = new EnumMap<>(GraphPropertyEnum.class);
-		Map<GraphPropertyEnum, Object> hasNotProps = new EnumMap<>(GraphPropertyEnum.class);
-		fillPropsMap(hasProps, hasNotProps, internalComponentType, componentTypeEnum, isAbstract, vertexType);
-		Either<List<GraphVertex>, TitanOperationStatus> getRes = titanDao.getByCriteria(vertexType, hasProps, hasNotProps, JsonParseFlagEnum.ParseMetadata);
-		if (getRes.isRight()) {
-			if (getRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
-				return Either.left(new ArrayList<>());
-			} else {
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getRes.right().value()));
-			}
-		} else {
-			// region -> Fetch non checked-out services
-			if (internalComponentType != null && internalComponentType.toLowerCase().trim().equals("service") && VertexTypeEnum.NODE_TYPE == vertexType) { // and NODE_TYPE==vertextype
-				Either<List<Service>, StorageOperationStatus> result = getLatestVersionNonCheckoutServicesMetadataOnly(new EnumMap<>(GraphPropertyEnum.class), new EnumMap<>(GraphPropertyEnum.class));
-				if (result.isRight()) {
-					log.debug("Failed to fetch services for");
-					return Either.right(result.right().value());
-				}
-				services = result.left().value();
-				if (CollectionUtils.isEmpty(services) && log.isTraceEnabled())
-					log.trace("No relevant services available");
-			}
-			// endregion
-			List<Component> nonAbstractLatestComponents = new ArrayList<>();
-			ComponentParametersView params = new ComponentParametersView(true);
-			params.setIgnoreAllVersions(false);
-			for (GraphVertex vertexComponent : getRes.left().value()) {
-				Either<ToscaElement, StorageOperationStatus> componentRes = topologyTemplateOperation.getLightComponent(vertexComponent, componentTypeEnum, params);
-				if (componentRes.isRight()) {
-					log.debug("Failed to fetch ligth element for {} error {}", vertexComponent.getUniqueId(), componentRes.right().value());
-					return Either.right(componentRes.right().value());
-				} else {
-					Component component = ModelConverter.convertFromToscaElement(componentRes.left().value());
-					nonAbstractLatestComponents.add(component);
-				}
-			}
-			if (CollectionUtils.isNotEmpty(services))
-				nonAbstractLatestComponents.addAll(services);
-			return Either.left(nonAbstractLatestComponents);
-		}
-	}
+    private Either<List<String>, StorageOperationStatus> getComponentUids(boolean isAbstract, ComponentTypeEnum componentTypeEnum, String internalComponentType) {
 
-	public Either<ComponentMetadataData, StorageOperationStatus> getLatestComponentMetadataByUuid(String componentUuid, JsonParseFlagEnum parseFlag, Boolean isHighest) {
+        Either<List<Component>, StorageOperationStatus> getToscaElementsRes = getLatestVersionNotAbstractMetadataOnly(isAbstract, componentTypeEnum, internalComponentType);
+        if (getToscaElementsRes.isRight()) {
+            return Either.right(getToscaElementsRes.right().value());
+        }
+        List<Component> collection = getToscaElementsRes.left().value();
+        List<String> componentUids;
+        if (collection == null) {
+            componentUids = new ArrayList<>();
+        } else {
+            componentUids = collection.stream()
+                    .map(Component::getUniqueId)
+                    .collect(Collectors.toList());
+        }
+        return Either.left(componentUids);
+    }
 
-		Either<ComponentMetadataData, StorageOperationStatus> result;
+    private ComponentParametersView buildComponentViewForNotAbstract() {
+        ComponentParametersView componentParametersView = new ComponentParametersView();
+        componentParametersView.disableAll();
+        componentParametersView.setIgnoreCategories(false);
+        componentParametersView.setIgnoreAllVersions(false);
+        return componentParametersView;
+    }
 
-		Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
+    public Either<Boolean, StorageOperationStatus> validateComponentNameExists(String name, ResourceTypeEnum resourceType, ComponentTypeEnum componentType) {
+        Either<Boolean, StorageOperationStatus> result = validateComponentNameUniqueness(name, resourceType, componentType);
+        if (result.isLeft()) {
+            result = Either.left(!result.left().value());
+        }
+        return result;
+    }
 
-		hasProperties.put(GraphPropertyEnum.UUID, componentUuid);
-		if (isHighest != null) {
-			hasProperties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, isHighest.booleanValue());
-		}
+    public Either<Boolean, StorageOperationStatus> validateComponentNameUniqueness(String name, ResourceTypeEnum resourceType, ComponentTypeEnum componentType) {
+        VertexTypeEnum vertexType = ModelConverter.isAtomicComponent(resourceType) ? VertexTypeEnum.NODE_TYPE : VertexTypeEnum.TOPOLOGY_TEMPLATE;
+        String normalizedName = ValidationUtils.normaliseComponentName(name);
+        Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
+        properties.put(GraphPropertyEnum.NORMALIZED_NAME, normalizedName);
+        properties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
 
-		Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
-		propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+        Either<List<GraphVertex>, TitanOperationStatus> vertexEither = titanDao.getByCriteria(vertexType, properties, JsonParseFlagEnum.NoParse);
+        if (vertexEither.isRight() && vertexEither.right().value() != TitanOperationStatus.NOT_FOUND) {
+            log.debug("failed to get vertex from graph with property normalizedName: {}", normalizedName);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexEither.right().value()));
+        }
+        List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null;
+        if (vertexList != null && !vertexList.isEmpty()) {
+            return Either.left(false);
+        } else {
+            return Either.left(true);
+        }
+    }
 
-		Either<List<GraphVertex>, TitanOperationStatus> getRes = titanDao.getByCriteria(null, hasProperties, propertiesNotToMatch, parseFlag);
-		if (getRes.isRight()) {
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getRes.right().value()));
-		} else {
-			List<ComponentMetadataData> latestVersionList = getRes.left().value().stream().map(ModelConverter::convertToComponentMetadata).collect(Collectors.toList());
-			ComponentMetadataData latestVersion = latestVersionList.size() == 1 ? latestVersionList.get(0)
-					: latestVersionList.stream().max((c1, c2) -> Double.compare(Double.parseDouble(c1.getMetadataDataDefinition().getVersion()), Double.parseDouble(c2.getMetadataDataDefinition().getVersion()))).get();
-			result = Either.left(latestVersion);
-		}
-		return result;
-	}
+    private void fillNodeTypePropsMap(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps, String internalComponentType) {
+        switch (internalComponentType.toLowerCase()) {
+            case "vf":
+            case "cvfc":
+                hasNotProps.put(GraphPropertyEnum.RESOURCE_TYPE, Arrays.asList(ResourceTypeEnum.VFCMT.name(), ResourceTypeEnum.Configuration.name()));
+                break;
+            case SERVICE:
+            case "pnf":
+            case "cr":
+                hasNotProps.put(GraphPropertyEnum.RESOURCE_TYPE, Arrays.asList(ResourceTypeEnum.VFC.name(), ResourceTypeEnum.VFCMT.name()));
+                break;
+            case "vl":
+                hasProps.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.VL.name());
+                break;
+            default:
+                break;
+        }
+    }
 
-	public Either<ComponentMetadataData, StorageOperationStatus> getComponentMetadata(String componentId) {
+    private void fillTopologyTemplatePropsMap(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps, ComponentTypeEnum componentTypeEnum) {
+        switch (componentTypeEnum) {
+            case RESOURCE:
+                hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
+                break;
+            case SERVICE:
+                hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
+                break;
+            default:
+                break;
+        }
+        hasNotProps.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.CVFC.name());
+    }
 
-		Either<ComponentMetadataData, StorageOperationStatus> result;
-		Either<GraphVertex, TitanOperationStatus> getRes = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
-		if (getRes.isRight()) {
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getRes.right().value()));
-		} else {
-			ComponentMetadataData componentMetadata = ModelConverter.convertToComponentMetadata(getRes.left().value());
-			result = Either.left(componentMetadata);
-		}
-		return result;
-	}
+    private void fillPropsMap(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps, String internalComponentType, ComponentTypeEnum componentTypeEnum, boolean isAbstract, VertexTypeEnum internalVertexType) {
+        hasNotProps.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
 
-	public Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractComponents(boolean isAbstract, Boolean isHighest, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids) {
+        hasNotProps.put(GraphPropertyEnum.IS_DELETED, true);
+        hasNotProps.put(GraphPropertyEnum.IS_ARCHIVED, true);
+        hasProps.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        if (VertexTypeEnum.NODE_TYPE == internalVertexType) {
+            hasProps.put(GraphPropertyEnum.IS_ABSTRACT, isAbstract);
+            if (internalComponentType != null) {
+                fillNodeTypePropsMap(hasProps, hasNotProps, internalComponentType);
+            }
+        } else {
+            fillTopologyTemplatePropsMap(hasProps, hasNotProps, componentTypeEnum);
+        }
+    }
 
-		Either<List<Component>, StorageOperationStatus> result = null;
-		List<Component> components = new ArrayList<>();
-		if (componentUids == null) {
-			Either<List<String>, StorageOperationStatus> componentUidsRes = getComponentUids(isAbstract, isHighest, componentTypeEnum, internalComponentType, componentUids);
-			if (componentUidsRes.isRight()) {
-				result = Either.right(componentUidsRes.right().value());
-			} else {
-				componentUids = componentUidsRes.left().value();
-			}
-		}
-		if (!componentUids.isEmpty()) {
-			for (String componentUid : componentUids) {
-				ComponentParametersView componentParametersView = buildComponentViewForNotAbstract();
-				if (internalComponentType != null && "vl".equalsIgnoreCase(internalComponentType)) {
-					componentParametersView.setIgnoreCapabilities(false);
-					componentParametersView.setIgnoreRequirements(false);
-				}
-				Either<ToscaElement, StorageOperationStatus> getToscaElementRes = nodeTemplateOperation.getToscaElementOperation(componentTypeEnum).getLightComponent(componentUid, componentTypeEnum, componentParametersView);
-				if (getToscaElementRes.isRight()) {
-					if (log.isDebugEnabled())
-						log.debug("Failed to fetch resource for error is {}", getToscaElementRes.right().value());
-					result = Either.right(getToscaElementRes.right().value());
-					break;
-				}
-				Component component = ModelConverter.convertFromToscaElement(getToscaElementRes.left().value());
-				component.setContactId(null);
-				component.setCreationDate(null);
-				component.setCreatorUserId(null);
-				component.setCreatorFullName(null);
-				component.setLastUpdateDate(null);
-				component.setLastUpdaterUserId(null);
-				component.setLastUpdaterFullName(null);
-				component.setNormalizedName(null);
-				components.add(component);
-			}
-		}
-		if (result == null) {
-			result = Either.left(components);
-		}
-		return result;
-	}
+    private List<VertexTypeEnum> getInternalVertexTypes(ComponentTypeEnum componentTypeEnum, String internalComponentType) {
+        List<VertexTypeEnum> internalVertexTypes = new ArrayList<>();
+        if (ComponentTypeEnum.RESOURCE == componentTypeEnum) {
+            internalVertexTypes.add(VertexTypeEnum.NODE_TYPE);
+        }
+        if (ComponentTypeEnum.SERVICE == componentTypeEnum || SERVICE.equalsIgnoreCase(internalComponentType)) {
+            internalVertexTypes.add(VertexTypeEnum.TOPOLOGY_TEMPLATE);
+        }
+        return internalVertexTypes;
+    }
 
-	private Either<List<String>, StorageOperationStatus> getComponentUids(boolean isAbstract, Boolean isHighest, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids) {
+    public Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractMetadataOnly(boolean isAbstract, ComponentTypeEnum componentTypeEnum, String internalComponentType) {
+        List<VertexTypeEnum> internalVertexTypes = getInternalVertexTypes(componentTypeEnum, internalComponentType);
+        List<Component> result = new ArrayList<>();
+        for (VertexTypeEnum vertexType : internalVertexTypes) {
+            Either<List<Component>, StorageOperationStatus> listByVertexType = getLatestVersionNotAbstractToscaElementsMetadataOnly(isAbstract, componentTypeEnum, internalComponentType, vertexType);
+            if (listByVertexType.isRight()) {
+                return listByVertexType;
+            }
+            result.addAll(listByVertexType.left().value());
+        }
+        return Either.left(result);
 
-		Either<List<String>, StorageOperationStatus> result = null;
-		Either<List<Component>, StorageOperationStatus> getToscaElementsRes = getLatestVersionNotAbstractMetadataOnly(isAbstract, isHighest, componentTypeEnum, internalComponentType);
-		if (getToscaElementsRes.isRight()) {
-			result = Either.right(getToscaElementsRes.right().value());
-		} else {
-			List<Component> collection = getToscaElementsRes.left().value();
-			if (collection == null) {
-				componentUids = new ArrayList<>();
-			} else {
-				componentUids = collection.stream().map(p -> p.getUniqueId()).collect(Collectors.toList());
-			}
-		}
-		if (result == null) {
-			result = Either.left(componentUids);
-		}
-		return result;
-	}
+    }
 
-	private ComponentParametersView buildComponentViewForNotAbstract() {
-		ComponentParametersView componentParametersView = new ComponentParametersView();
-		componentParametersView.disableAll();
-		componentParametersView.setIgnoreCategories(false);
-		componentParametersView.setIgnoreAllVersions(false);
-		return componentParametersView;
-	}
+    private Either<List<Component>, StorageOperationStatus> getLatestComponentListByUuid(String componentUuid, Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        if (additionalPropertiesToMatch != null) {
+            propertiesToMatch.putAll(additionalPropertiesToMatch);
+        }
+        propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        return getComponentListByUuid(componentUuid, propertiesToMatch);
+    }
 
-	public Either<Boolean, StorageOperationStatus> validateComponentNameExists(String name, ResourceTypeEnum resourceType, ComponentTypeEnum componentType) {
-		Either<Boolean, StorageOperationStatus> result = validateComponentNameUniqueness(name, resourceType, componentType);
-		if (result.isLeft()) {
-			result = Either.left(!result.left().value());
-		}
-		return result;
-	}
+    public Either<Component, StorageOperationStatus> getComponentByUuidAndVersion(String componentUuid, String version) {
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
 
-	public Either<Boolean, StorageOperationStatus> validateComponentNameUniqueness(String name, ResourceTypeEnum resourceType, ComponentTypeEnum componentType) {
-		VertexTypeEnum vertexType = ModelConverter.isAtomicComponent(resourceType) ? VertexTypeEnum.NODE_TYPE : VertexTypeEnum.TOPOLOGY_TEMPLATE;
-		String normalizedName = ValidationUtils.normaliseComponentName(name);
-		Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
-		properties.put(GraphPropertyEnum.NORMALIZED_NAME, normalizedName);
-		properties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
+        propertiesToMatch.put(GraphPropertyEnum.UUID, componentUuid);
+        propertiesToMatch.put(GraphPropertyEnum.VERSION, version);
 
-		Either<List<GraphVertex>, TitanOperationStatus> vertexEither = titanDao.getByCriteria(vertexType, properties, JsonParseFlagEnum.NoParse);
-		if (vertexEither.isRight() && vertexEither.right().value() != TitanOperationStatus.NOT_FOUND) {
-			log.debug("failed to get vertex from graph with property normalizedName: {}", normalizedName);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexEither.right().value()));
-		}
-		List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null;
-		if (vertexList != null && !vertexList.isEmpty()) {
-			return Either.left(false);
-		} else {
-			return Either.left(true);
-		}
-	}
+        Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+        Either<List<GraphVertex>, TitanOperationStatus> vertexEither = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
+        if (vertexEither.isRight()) {
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexEither.right().value()));
+        }
 
-	private void fillNodeTypePropsMap(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps, String internalComponentType) {
-		switch (internalComponentType.toLowerCase()) {
-		case "vf":
-		case "cvfc":
-			hasNotProps.put(GraphPropertyEnum.RESOURCE_TYPE, Arrays.asList(ResourceTypeEnum.VFCMT.name(), ResourceTypeEnum.Configuration.name()));
-			break;
-		case "service":
-		case "pnf":
-		case "cr":
-			hasNotProps.put(GraphPropertyEnum.RESOURCE_TYPE, Arrays.asList(ResourceTypeEnum.VFC.name(), ResourceTypeEnum.VFCMT.name()));
-			break;
-		case "vl":
-			hasProps.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.VL.name());
-			break;
-		default:
-			break;
-		}
-	}
+        List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null;
+        if (vertexList == null || vertexList.isEmpty() || vertexList.size() > 1) {
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
 
-	private void fillTopologyTemplatePropsMap(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps, ComponentTypeEnum componentTypeEnum, String internalComponentType) {
-		switch (componentTypeEnum) {
-		case RESOURCE:
-			hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
-			break;
-		case SERVICE:
-			hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
-			break;
-		default:
-			break;
-		}
-		switch (internalComponentType.toLowerCase()) {
-		case "vf":
-		case "cvfc":
-			hasProps.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.CVFC.name());
-			break;
-		case "service":
-			hasNotProps.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.CVFC.name());
-			break;
-		default:
-			break;
-		}
-	}
+        return getToscaElementByOperation(vertexList.get(0));
+    }
 
-	private void fillPropsMap(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps, String internalComponentType, ComponentTypeEnum componentTypeEnum, boolean isAbstract, VertexTypeEnum internalVertexType) {
-		hasNotProps.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
+    public Either<List<Component>, StorageOperationStatus> getComponentListByUuid(String componentUuid, Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
 
-		hasNotProps.put(GraphPropertyEnum.IS_DELETED, true);
-		hasProps.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
-		if (VertexTypeEnum.NODE_TYPE == internalVertexType) {
-			hasProps.put(GraphPropertyEnum.IS_ABSTRACT, isAbstract);
-			if (internalComponentType != null) {
-				fillNodeTypePropsMap(hasProps, hasNotProps, internalComponentType);
-			}
-		} else {
-			fillTopologyTemplatePropsMap(hasProps, hasNotProps, componentTypeEnum, internalComponentType);
-		}
-	}
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
 
-	private List<VertexTypeEnum> getInternalVertexTypes(ComponentTypeEnum componentTypeEnum, String internalComponentType) {
-		List<VertexTypeEnum> internalVertexTypes = new ArrayList<>();
-		if (ComponentTypeEnum.RESOURCE == componentTypeEnum) {
-			internalVertexTypes.add(VertexTypeEnum.NODE_TYPE);
-		}
-		if (ComponentTypeEnum.SERVICE == componentTypeEnum || "service".equalsIgnoreCase(internalComponentType) || "vf".equalsIgnoreCase(internalComponentType)) {
-			internalVertexTypes.add(VertexTypeEnum.TOPOLOGY_TEMPLATE);
-		}
-		return internalVertexTypes;
-	}
+        if (additionalPropertiesToMatch != null) {
+            propertiesToMatch.putAll(additionalPropertiesToMatch);
+        }
 
-	public Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractMetadataOnly(boolean isAbstract, Boolean isHighest, ComponentTypeEnum componentTypeEnum, String internalComponentType) {
-		List<VertexTypeEnum> internalVertexTypes = getInternalVertexTypes(componentTypeEnum, internalComponentType);
-		List<Component> result = new ArrayList<>();
-		for (VertexTypeEnum vertexType : internalVertexTypes) {
-			Either<List<Component>, StorageOperationStatus> listByVertexType = getLatestVersionNotAbstractToscaElementsMetadataOnly(isAbstract, isHighest, componentTypeEnum, internalComponentType, vertexType);
-			if (listByVertexType.isRight()) {
-				return listByVertexType;
-			}
-			result.addAll(listByVertexType.left().value());
-		}
-		return Either.left(result);
+        propertiesToMatch.put(GraphPropertyEnum.UUID, componentUuid);
 
-	}
+        Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+        propertiesNotToMatch.put(GraphPropertyEnum.IS_ARCHIVED, true); //US382674, US382683
 
-	private Either<List<Component>, StorageOperationStatus> getLatestComponentListByUuid(String componentUuid, Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
-		Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
-		if (additionalPropertiesToMatch != null) {
-			propertiesToMatch.putAll(additionalPropertiesToMatch);
-		}
-		propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
-		Either<List<Component>, StorageOperationStatus> componentListByUuid = getComponentListByUuid(componentUuid, propertiesToMatch);
-		return componentListByUuid;
-	}
+        Either<List<GraphVertex>, TitanOperationStatus> vertexEither = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
 
-	public Either<Component, StorageOperationStatus> getComponentByUuidAndVersion(String componentUuid, String version) {
-		Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        if (vertexEither.isRight()) {
+            log.debug("Couldn't fetch metadata for component with uuid {}, error: {}", componentUuid, vertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexEither.right().value()));
+        }
+        List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null;
 
-		propertiesToMatch.put(GraphPropertyEnum.UUID, componentUuid);
-		propertiesToMatch.put(GraphPropertyEnum.VERSION, version);
+        if (vertexList == null || vertexList.isEmpty()) {
+            log.debug("Component with uuid {} was not found", componentUuid);
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
 
-		Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
-		propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
-		Either<List<GraphVertex>, TitanOperationStatus> vertexEither = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
-		if (vertexEither.isRight()) {
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexEither.right().value()));
-		}
+        ArrayList<Component> latestComponents = new ArrayList<>();
+        for (GraphVertex vertex : vertexList) {
+            Either<Component, StorageOperationStatus> toscaElementByOperation = getToscaElementByOperation(vertex);
 
-		List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null;
-		if (vertexList == null || vertexList.isEmpty() || vertexList.size() > 1) {
-			return Either.right(StorageOperationStatus.NOT_FOUND);
-		}
+            if (toscaElementByOperation.isRight()) {
+                log.debug("Could not fetch the following Component by UUID {}", vertex.getUniqueId());
+                return Either.right(toscaElementByOperation.right().value());
+            }
 
-		return getToscaElementByOperation(vertexList.get(0));
-	}
+            latestComponents.add(toscaElementByOperation.left().value());
+        }
 
-	public Either<List<Component>, StorageOperationStatus> getComponentListByUuid(String componentUuid, Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
+        if (latestComponents.size() > 1) {
+            for (Component component : latestComponents) {
+                if (component.isHighestVersion()) {
+                    LinkedList<Component> highestComponent = new LinkedList<>();
+                    highestComponent.add(component);
+                    return Either.left(highestComponent);
+                }
+            }
+        }
 
-		Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        return Either.left(latestComponents);
+    }
 
-		if (additionalPropertiesToMatch != null) {
-			propertiesToMatch.putAll(additionalPropertiesToMatch);
-		}
+    public Either<Component, StorageOperationStatus> getLatestServiceByUuid(String serviceUuid) {
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
+        return getLatestComponentByUuid(serviceUuid, propertiesToMatch);
+    }
 
-		propertiesToMatch.put(GraphPropertyEnum.UUID, componentUuid);
+    public Either<Component, StorageOperationStatus> getLatestComponentByUuid(String componentUuid) {
+        return getLatestComponentByUuid(componentUuid, null);
+    }
 
-		Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
-		propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+    public Either<Component, StorageOperationStatus> getLatestComponentByUuid(String componentUuid, Map<GraphPropertyEnum, Object> propertiesToMatch) {
 
-		Either<List<GraphVertex>, TitanOperationStatus> vertexEither = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
+        Either<List<Component>, StorageOperationStatus> latestVersionListEither = getLatestComponentListByUuid(componentUuid, propertiesToMatch);
 
-		if (vertexEither.isRight()) {
-			log.debug("Couldn't fetch metadata for component with type {} and uuid {}, error: {}", componentUuid, vertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexEither.right().value()));
-		}
-		List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null;
+        if (latestVersionListEither.isRight()) {
+            return Either.right(latestVersionListEither.right().value());
+        }
 
-		if (vertexList == null || vertexList.isEmpty()) {
-			log.debug("Component with uuid {} was not found", componentUuid);
-			return Either.right(StorageOperationStatus.NOT_FOUND);
-		}
+        List<Component> latestVersionList = latestVersionListEither.left().value();
 
-		ArrayList<Component> latestComponents = new ArrayList<>();
-		for (GraphVertex vertex : vertexList) {
-			Either<Component, StorageOperationStatus> toscaElementByOperation = getToscaElementByOperation(vertex);
+        if (latestVersionList.isEmpty()) {
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        Component component = latestVersionList.size() == 1 ? latestVersionList.get(0) : latestVersionList.stream().max((c1, c2) -> Double.compare(Double.parseDouble(c1.getVersion()), Double.parseDouble(c2.getVersion()))).get();
 
-			if (toscaElementByOperation.isRight()) {
-				log.debug("Could not fetch the following Component by UUID {}", vertex.getUniqueId());
-				return Either.right(toscaElementByOperation.right().value());
-			}
+        return Either.left(component);
+    }
 
-			latestComponents.add(toscaElementByOperation.left().value());
-		}
+    public Either<List<Resource>, StorageOperationStatus> getAllCertifiedResources(boolean isAbstract, Boolean isHighest) {
 
-		if (latestComponents.size() > 1) {
-			for (Component component : latestComponents) {
-				if (component.isHighestVersion()) {
-					LinkedList<Component> highestComponent = new LinkedList<>();
-					highestComponent.add(component);
-					return Either.left(highestComponent);
-				}
-			}
-		}
+        List<Resource> resources = new ArrayList<>();
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
 
-		return Either.left(latestComponents);
-	}
+        propertiesToMatch.put(GraphPropertyEnum.IS_ABSTRACT, isAbstract);
+        if (isHighest != null) {
+            propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, isHighest);
+        }
+        propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
+        propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
+        propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
 
-	public Either<Component, StorageOperationStatus> getLatestServiceByUuid(String serviceUuid) {
-		Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
-		propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
-		return getLatestComponentByUuid(serviceUuid, propertiesToMatch);
-	}
+        Either<List<GraphVertex>, TitanOperationStatus> getResourcesRes = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
 
-	public Either<Component, StorageOperationStatus> getLatestComponentByUuid(String componentUuid) {
-		return getLatestComponentByUuid(componentUuid, null);
-	}
+        if (getResourcesRes.isRight()) {
+            log.debug("Failed to fetch all certified resources. Status is {}", getResourcesRes.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResourcesRes.right().value()));
+        }
+        List<GraphVertex> resourceVerticies = getResourcesRes.left().value();
+        for (GraphVertex resourceV : resourceVerticies) {
+            Either<Resource, StorageOperationStatus> getResourceRes = getToscaElement(resourceV);
+            if (getResourceRes.isRight()) {
+                return Either.right(getResourceRes.right().value());
+            }
+            resources.add(getResourceRes.left().value());
+        }
+        return Either.left(resources);
+    }
 
-	public Either<Component, StorageOperationStatus> getLatestComponentByUuid(String componentUuid, Map<GraphPropertyEnum, Object> propertiesToMatch) {
+    public <T extends Component> Either<T, StorageOperationStatus> getLatestByNameAndVersion(String name, String version, JsonParseFlagEnum parseFlag) {
+        Either<T, StorageOperationStatus> result;
 
-		Either<List<Component>, StorageOperationStatus> latestVersionListEither = getLatestComponentListByUuid(componentUuid, propertiesToMatch);
+        Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
+        Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
 
-		if (latestVersionListEither.isRight()) {
-			return Either.right(latestVersionListEither.right().value());
-		}
+        hasProperties.put(GraphPropertyEnum.NAME, name);
+        hasProperties.put(GraphPropertyEnum.VERSION, version);
+        hasProperties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
 
-		List<Component> latestVersionList = latestVersionListEither.left().value();
+        hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true);
 
-		if (latestVersionList.isEmpty()) {
-			return Either.right(StorageOperationStatus.NOT_FOUND);
-		}
-		Component component = latestVersionList.size() == 1 ? latestVersionList.get(0) : latestVersionList.stream().max((c1, c2) -> Double.compare(Double.parseDouble(c1.getVersion()), Double.parseDouble(c2.getVersion()))).get();
+        Either<List<GraphVertex>, TitanOperationStatus> getResourceRes = titanDao.getByCriteria(null, hasProperties, hasNotProperties, parseFlag);
+        if (getResourceRes.isRight()) {
+            TitanOperationStatus status = getResourceRes.right().value();
+            log.debug("failed to find resource with name {}, version {}. Status is {} ", name, version, status);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            return result;
+        }
+        return getToscaElementByOperation(getResourceRes.left().value().get(0));
+    }
 
-		return Either.left(component);
-	}
+    public Either<Resource, StorageOperationStatus> getLatestComponentByCsarOrName(ComponentTypeEnum componentType, String csarUUID, String systemName) {
+        return getLatestComponentByCsarOrName(componentType, csarUUID, systemName, JsonParseFlagEnum.ParseAll);
+    }
 
-	public Either<List<Resource>, StorageOperationStatus> getAllCertifiedResources(boolean isAbstract, Boolean isHighest) {
+    public Either<Resource, StorageOperationStatus> getLatestComponentByCsarOrName(ComponentTypeEnum componentType, String csarUUID, String systemName, JsonParseFlagEnum parseFlag) {
+        Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
+        Map<GraphPropertyEnum, Object> propsHasNot = new EnumMap<>(GraphPropertyEnum.class);
+        props.put(GraphPropertyEnum.CSAR_UUID, csarUUID);
+        props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        if (componentType != null) {
+            props.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
+        }
+        propsHasNot.put(GraphPropertyEnum.IS_DELETED, true);
 
-		List<Resource> resources = new ArrayList<>();
-		Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
-		Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        GraphVertex resourceMetadataData = null;
+        List<GraphVertex> resourceMetadataDataList = null;
+        Either<List<GraphVertex>, TitanOperationStatus> byCsar = titanDao.getByCriteria(null, props, propsHasNot, JsonParseFlagEnum.ParseMetadata);
+        if (byCsar.isRight()) {
+            if (TitanOperationStatus.NOT_FOUND == byCsar.right().value()) {
+                // Fix Defect DE256036
+                if (StringUtils.isEmpty(systemName)) {
+                    return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.NOT_FOUND));
+                }
 
-		propertiesToMatch.put(GraphPropertyEnum.IS_ABSTRACT, isAbstract);
-		if (isHighest != null) {
-			propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, isHighest.booleanValue());
-		}
-		propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
-		propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
-		propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+                props.clear();
+                props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+                props.put(GraphPropertyEnum.SYSTEM_NAME, systemName);
+                Either<List<GraphVertex>, TitanOperationStatus> bySystemname = titanDao.getByCriteria(null, props, JsonParseFlagEnum.ParseMetadata);
+                if (bySystemname.isRight()) {
+                    log.debug("getLatestResourceByCsarOrName - Failed to find by system name {}  error {} ", systemName, bySystemname.right().value());
+                    return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(bySystemname.right().value()));
+                }
+                if (bySystemname.left().value().size() > 2) {
+                    log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) must return only 2 latest version, but was returned - {}", bySystemname.left().value().size());
+                    return Either.right(StorageOperationStatus.GENERAL_ERROR);
+                }
+                resourceMetadataDataList = bySystemname.left().value();
+                if (resourceMetadataDataList.size() == 1) {
+                    resourceMetadataData = resourceMetadataDataList.get(0);
+                } else {
+                    for (GraphVertex curResource : resourceMetadataDataList) {
+                        if (!((String) curResource.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals("CERTIFIED")) {
+                            resourceMetadataData = curResource;
+                            break;
+                        }
+                    }
+                }
+                if (resourceMetadataData == null) {
+                    log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) returned 2 latest CERTIFIED versions");
+                    return Either.right(StorageOperationStatus.GENERAL_ERROR);
+                }
+                if (resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID) != null && !((String) resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID)).equals(csarUUID)) {
+                    log.debug("getLatestResourceByCsarOrName - same system name {} but different csarUUID. exist {} and new {} ", systemName, resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID), csarUUID);
+                    // correct error will be returned from create flow. with all
+                    // correct audit records!!!!!
+                    return Either.right(StorageOperationStatus.NOT_FOUND);
+                }
+                return getToscaElement((String) resourceMetadataData.getUniqueId());
+            }
+        } else {
+            resourceMetadataDataList = byCsar.left().value();
+            if (resourceMetadataDataList.size() > 2) {
+                log.debug("getLatestResourceByCsarOrName - getByCriteria(by csar) must return only 2 latest version, but was returned - {}", byCsar.left().value().size());
+                return Either.right(StorageOperationStatus.GENERAL_ERROR);
+            }
+            if (resourceMetadataDataList.size() == 1) {
+                resourceMetadataData = resourceMetadataDataList.get(0);
+            } else {
+                for (GraphVertex curResource : resourceMetadataDataList) {
+                    if (!((String) curResource.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals("CERTIFIED")) {
+                        resourceMetadataData = curResource;
+                        break;
+                    }
+                }
+            }
+            if (resourceMetadataData == null) {
+                log.debug("getLatestResourceByCsarOrName - getByCriteria(by csar) returned 2 latest CERTIFIED versions");
+                return Either.right(StorageOperationStatus.GENERAL_ERROR);
+            }
+            return getToscaElement((String) resourceMetadataData.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID), parseFlag);
+        }
+        return null;
+    }
 
-		Either<List<GraphVertex>, TitanOperationStatus> getResourcesRes = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
+    public Either<Boolean, StorageOperationStatus> validateToscaResourceNameExtends(String templateNameCurrent, String templateNameExtends) {
 
-		if (getResourcesRes.isRight()) {
-			log.debug("Failed to fetch all certified resources. Status is {}", getResourcesRes.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResourcesRes.right().value()));
-		}
-		List<GraphVertex> resourceVerticies = getResourcesRes.left().value();
-		for (GraphVertex resourceV : resourceVerticies) {
-			Either<Resource, StorageOperationStatus> getResourceRes = getToscaElement(resourceV);
-			if (getResourceRes.isRight()) {
-				return Either.right(getResourceRes.right().value());
-			}
-			resources.add(getResourceRes.left().value());
-		}
-		return Either.left(resources);
-	}
+        String currentTemplateNameChecked = templateNameExtends;
 
-	public <T extends Component> Either<T, StorageOperationStatus> getLatestByNameAndVersion(String name, String version, JsonParseFlagEnum parseFlag) {
-		Either<T, StorageOperationStatus> result;
+        while (currentTemplateNameChecked != null && !currentTemplateNameChecked.equalsIgnoreCase(templateNameCurrent)) {
+            Either<Resource, StorageOperationStatus> latestByToscaResourceName = getLatestByToscaResourceName(currentTemplateNameChecked);
 
-		Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
-		Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
+            if (latestByToscaResourceName.isRight()) {
+                return latestByToscaResourceName.right().value() == StorageOperationStatus.NOT_FOUND ? Either.left(false) : Either.right(latestByToscaResourceName.right().value());
+            }
 
-		hasProperties.put(GraphPropertyEnum.NAME, name);
-		hasProperties.put(GraphPropertyEnum.VERSION, version);
-		hasProperties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+            Resource value = latestByToscaResourceName.left().value();
 
-		hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true);
+            if (value.getDerivedFrom() != null) {
+                currentTemplateNameChecked = value.getDerivedFrom().get(0);
+            } else {
+                currentTemplateNameChecked = null;
+            }
+        }
 
-		Either<List<GraphVertex>, TitanOperationStatus> getResourceRes = titanDao.getByCriteria(null, hasProperties, hasNotProperties, parseFlag);
-		if (getResourceRes.isRight()) {
-			TitanOperationStatus status = getResourceRes.right().value();
-			log.debug("failed to find resource with name {}, version {}. Status is {} ", name, version, status);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			return result;
-		}
-		return getToscaElementByOperation(getResourceRes.left().value().get(0));
-	}
+        return (currentTemplateNameChecked != null && currentTemplateNameChecked.equalsIgnoreCase(templateNameCurrent)) ? Either.left(true) : Either.left(false);
+    }
 
-	public Either<Resource, StorageOperationStatus> getLatestComponentByCsarOrName(ComponentTypeEnum componentType, String csarUUID, String systemName) {
-		return getLatestComponentByCsarOrName(componentType, csarUUID, systemName, false, JsonParseFlagEnum.ParseAll);
-	}
+    public Either<List<Component>, StorageOperationStatus> fetchMetaDataByResourceType(String resourceType, ComponentParametersView filterBy) {
+        Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
+        props.put(GraphPropertyEnum.RESOURCE_TYPE, resourceType);
+        props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        Map<GraphPropertyEnum, Object> propsHasNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        propsHasNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+        Either<List<GraphVertex>, TitanOperationStatus> resourcesByTypeEither = titanDao.getByCriteria(null, props, propsHasNotToMatch, JsonParseFlagEnum.ParseMetadata);
 
-	public Either<Resource, StorageOperationStatus> getLatestComponentByCsarOrName(ComponentTypeEnum componentType, String csarUUID, String systemName, boolean allowDeleted, JsonParseFlagEnum parseFlag) {
-		Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
-		props.put(GraphPropertyEnum.CSAR_UUID, csarUUID);
-		props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
-		if (componentType != null) {
-			props.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
-		}
-		Map<GraphPropertyEnum, Object> propsHasNot = new EnumMap<>(GraphPropertyEnum.class);
-		propsHasNot.put(GraphPropertyEnum.IS_DELETED, true);
+        if (resourcesByTypeEither.isRight()) {
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourcesByTypeEither.right().value()));
+        }
 
-		GraphVertex resourceMetadataData = null;
-		List<GraphVertex> resourceMetadataDataList = null;
-		Either<List<GraphVertex>, TitanOperationStatus> byCsar = titanDao.getByCriteria(null, props, propsHasNot, JsonParseFlagEnum.ParseMetadata);
-		if (byCsar.isRight()) {
-			if (TitanOperationStatus.NOT_FOUND == byCsar.right().value()) {
-				// Fix Defect DE256036
-				if (StringUtils.isEmpty(systemName)) {
-					return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.NOT_FOUND));
-				}
+        List<GraphVertex> vertexList = resourcesByTypeEither.left().value();
+        List<Component> components = new ArrayList<>();
 
-				props.clear();
-				props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
-				props.put(GraphPropertyEnum.SYSTEM_NAME, systemName);
-				Either<List<GraphVertex>, TitanOperationStatus> bySystemname = titanDao.getByCriteria(null, props, JsonParseFlagEnum.ParseMetadata);
-				if (bySystemname.isRight()) {
-					log.debug("getLatestResourceByCsarOrName - Failed to find by system name {}  error {} ", systemName, bySystemname.right().value());
-					return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(bySystemname.right().value()));
-				}
-				if (bySystemname.left().value().size() > 2) {
-					log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) must return only 2 latest version, but was returned - {}", bySystemname.left().value().size());
-					return Either.right(StorageOperationStatus.GENERAL_ERROR);
-				}
-				resourceMetadataDataList = bySystemname.left().value();
-				if (resourceMetadataDataList.size() == 1) {
-					resourceMetadataData = resourceMetadataDataList.get(0);
-				} else {
-					for (GraphVertex curResource : resourceMetadataDataList) {
-						if (!((String) curResource.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals("CERTIFIED")) {
-							resourceMetadataData = curResource;
-							break;
-						}
-					}
-				}
-				if (resourceMetadataData == null) {
-					log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) returned 2 latest CERTIFIED versions");
-					return Either.right(StorageOperationStatus.GENERAL_ERROR);
-				}
-				if (resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID) != null && !((String) resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID)).equals(csarUUID)) {
-					log.debug("getLatestResourceByCsarOrName - same system name {} but different csarUUID. exist {} and new {} ", systemName, resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID), csarUUID);
-					// correct error will be returned from create flow. with all
-					// correct audit records!!!!!
-					return Either.right(StorageOperationStatus.NOT_FOUND);
-				}
-				Either<Resource, StorageOperationStatus> resource = getToscaElement((String) resourceMetadataData.getUniqueId());
-				return resource;
-			}
-		} else {
-			resourceMetadataDataList = byCsar.left().value();
-			if (resourceMetadataDataList.size() > 2) {
-				log.debug("getLatestResourceByCsarOrName - getByCriteria(by csar) must return only 2 latest version, but was returned - {}", byCsar.left().value().size());
-				return Either.right(StorageOperationStatus.GENERAL_ERROR);
-			}
-			if (resourceMetadataDataList.size() == 1) {
-				resourceMetadataData = resourceMetadataDataList.get(0);
-			} else {
-				for (GraphVertex curResource : resourceMetadataDataList) {
-					if (!((String) curResource.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals("CERTIFIED")) {
-						resourceMetadataData = curResource;
-						break;
-					}
-				}
-			}
-			if (resourceMetadataData == null) {
-				log.debug("getLatestResourceByCsarOrName - getByCriteria(by csar) returned 2 latest CERTIFIED versions");
-				return Either.right(StorageOperationStatus.GENERAL_ERROR);
-			}
-			Either<Resource, StorageOperationStatus> resource = getToscaElement((String) resourceMetadataData.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID), parseFlag);
-			return resource;
-		}
-		return null;
-	}
+        for (GraphVertex vertex : vertexList) {
+            components.add(getToscaElementByOperation(vertex, filterBy).left().value());
+        }
 
-	public Either<Boolean, StorageOperationStatus> validateToscaResourceNameExtends(String templateNameCurrent, String templateNameExtends) {
+        return Either.left(components);
+    }
 
-		String currentTemplateNameChecked = templateNameExtends;
+    public void commit() {
+        titanDao.commit();
+    }
 
-		while (currentTemplateNameChecked != null && !currentTemplateNameChecked.equalsIgnoreCase(templateNameCurrent)) {
-			Either<Resource, StorageOperationStatus> latestByToscaResourceName = getLatestByToscaResourceName(currentTemplateNameChecked);
+    public Either<Service, StorageOperationStatus> updateDistributionStatus(Service service, User user, DistributionStatusEnum distributionStatus) {
+        Either<GraphVertex, StorageOperationStatus> updateDistributionStatus = topologyTemplateOperation.updateDistributionStatus(service.getUniqueId(), user, distributionStatus);
+        if (updateDistributionStatus.isRight()) {
+            return Either.right(updateDistributionStatus.right().value());
+        }
+        GraphVertex serviceV = updateDistributionStatus.left().value();
+        service.setDistributionStatus(distributionStatus);
+        service.setLastUpdateDate((Long) serviceV.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE));
+        return Either.left(service);
+    }
 
-			if (latestByToscaResourceName.isRight()) {
-				return latestByToscaResourceName.right().value() == StorageOperationStatus.NOT_FOUND ? Either.left(false) : Either.right(latestByToscaResourceName.right().value());
-			}
+    public Either<ComponentMetadataData, StorageOperationStatus> updateComponentLastUpdateDateOnGraph(Component component) {
 
-			Resource value = latestByToscaResourceName.left().value();
+        Either<ComponentMetadataData, StorageOperationStatus> result = null;
+        GraphVertex serviceVertex;
+        Either<GraphVertex, TitanOperationStatus> updateRes = null;
+        Either<GraphVertex, TitanOperationStatus> getRes = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
+        if (getRes.isRight()) {
+            TitanOperationStatus status = getRes.right().value();
+            log.error("Failed to fetch component {}. status is {}", component.getUniqueId(), status);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
+        if (result == null) {
+            serviceVertex = getRes.left().value();
+            long lastUpdateDate = System.currentTimeMillis();
+            serviceVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, lastUpdateDate);
+            component.setLastUpdateDate(lastUpdateDate);
+            updateRes = titanDao.updateVertex(serviceVertex);
+            if (updateRes.isRight()) {
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateRes.right().value()));
+            }
+        }
+        if (result == null) {
+            result = Either.left(ModelConverter.convertToComponentMetadata(updateRes.left().value()));
+        }
+        return result;
+    }
 
-			if (value.getDerivedFrom() != null) {
-				currentTemplateNameChecked = value.getDerivedFrom().get(0);
-			} else {
-				currentTemplateNameChecked = null;
-			}
-		}
+    public TitanDao getTitanDao() {
+        return titanDao;
+    }
 
-		return (currentTemplateNameChecked != null && currentTemplateNameChecked.equalsIgnoreCase(templateNameCurrent)) ? Either.left(true) : Either.left(false);
-	}
+    public Either<List<Service>, StorageOperationStatus> getCertifiedServicesWithDistStatus(Set<DistributionStatusEnum> distStatus) {
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
 
-	public Either<List<Component>, StorageOperationStatus> fetchMetaDataByResourceType(String resourceType, ComponentParametersView filterBy) {
-		Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
-		props.put(GraphPropertyEnum.RESOURCE_TYPE, resourceType);
-		props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
-		Map<GraphPropertyEnum, Object> propsHasNotToMatch = new HashMap<>();
-		propsHasNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
-		Either<List<GraphVertex>, TitanOperationStatus> resourcesByTypeEither = titanDao.getByCriteria(null, props, propsHasNotToMatch, JsonParseFlagEnum.ParseMetadata);
+        return getServicesWithDistStatus(distStatus, propertiesToMatch);
+    }
 
-		if (resourcesByTypeEither.isRight()) {
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourcesByTypeEither.right().value()));
-		}
+    public Either<List<Service>, StorageOperationStatus> getServicesWithDistStatus(Set<DistributionStatusEnum> distStatus, Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
 
-		List<GraphVertex> vertexList = resourcesByTypeEither.left().value();
-		List<Component> components = new ArrayList<>();
+        List<Service> servicesAll = new ArrayList<>();
 
-		for (GraphVertex vertex : vertexList) {
-			components.add(getToscaElementByOperation(vertex, filterBy).left().value());
-		}
+        Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
 
-		return Either.left(components);
-	}
+        if (additionalPropertiesToMatch != null && !additionalPropertiesToMatch.isEmpty()) {
+            propertiesToMatch.putAll(additionalPropertiesToMatch);
+        }
 
-	public void commit() {
-		titanDao.commit();
-	}
+        propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
 
-	public Either<Service, StorageOperationStatus> updateDistributionStatus(Service service, User user, DistributionStatusEnum distributionStatus) {
-		Either<GraphVertex, StorageOperationStatus> updateDistributionStatus = topologyTemplateOperation.updateDistributionStatus(service.getUniqueId(), user, distributionStatus);
-		if (updateDistributionStatus.isRight()) {
-			return Either.right(updateDistributionStatus.right().value());
-		}
-		GraphVertex serviceV = updateDistributionStatus.left().value();
-		service.setDistributionStatus(distributionStatus);
-		service.setLastUpdateDate((Long) serviceV.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE));
-		return Either.left(service);
-	}
+        propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
 
-	public Either<ComponentMetadataData, StorageOperationStatus> updateComponentLastUpdateDateOnGraph(Component component, Long modificationTime) {
+        if (distStatus != null && !distStatus.isEmpty()) {
+            for (DistributionStatusEnum state : distStatus) {
+                propertiesToMatch.put(GraphPropertyEnum.DISTRIBUTION_STATUS, state.name());
+                Either<List<Service>, StorageOperationStatus> fetchServicesByCriteria = fetchServicesByCriteria(servicesAll, propertiesToMatch, propertiesNotToMatch);
+                if (fetchServicesByCriteria.isRight()) {
+                    return fetchServicesByCriteria;
+                } else {
+                    servicesAll = fetchServicesByCriteria.left().value();
+                }
+            }
+            return Either.left(servicesAll);
+        } else {
+            return fetchServicesByCriteria(servicesAll, propertiesToMatch, propertiesNotToMatch);
+        }
+    }
 
-		Either<ComponentMetadataData, StorageOperationStatus> result = null;
-		GraphVertex serviceVertex;
-		Either<GraphVertex, TitanOperationStatus> updateRes = null;
-		Either<GraphVertex, TitanOperationStatus> getRes = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
-		if (getRes.isRight()) {
-			TitanOperationStatus status = getRes.right().value();
-			log.error("Failed to fetch component {}. status is {}", component.getUniqueId(), status);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-		}
-		if (result == null) {
-			serviceVertex = getRes.left().value();
-			long lastUpdateDate = System.currentTimeMillis();
-			serviceVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, lastUpdateDate);
-			component.setLastUpdateDate(lastUpdateDate);
-			updateRes = titanDao.updateVertex(serviceVertex);
-			if (updateRes.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateRes.right().value()));
-			}
-		}
-		if (result == null) {
-			result = Either.left(ModelConverter.convertToComponentMetadata(updateRes.left().value()));
-		}
-		return result;
-	}
+    private Either<List<Service>, StorageOperationStatus> fetchServicesByCriteria(List<Service> servicesAll, Map<GraphPropertyEnum, Object> propertiesToMatch, Map<GraphPropertyEnum, Object> propertiesNotToMatch) {
+        Either<List<GraphVertex>, TitanOperationStatus> getRes = titanDao.getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
+        if (getRes.isRight()) {
+            if (getRes.right().value() != TitanOperationStatus.NOT_FOUND) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch certified services by match properties {} not match properties {} . Status is {}. ", propertiesToMatch, propertiesNotToMatch, getRes.right().value());
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getRes.right().value()));
+            }
+        } else {
+            for (GraphVertex vertex : getRes.left().value()) {
+                Either<ToscaElement, StorageOperationStatus> getServiceRes = topologyTemplateOperation.getLightComponent(vertex, ComponentTypeEnum.SERVICE, new ComponentParametersView(true));
 
-	public TitanDao getTitanDao() {
-		return titanDao;
-	}
+                if (getServiceRes.isRight()) {
+                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch certified service {}. Status is {}. ", vertex.getJsonMetadataField(JsonPresentationFields.NAME), getServiceRes.right().value());
+                    return Either.right(getServiceRes.right().value());
+                } else {
+                    servicesAll.add(ModelConverter.convertFromToscaElement(getServiceRes.left().value()));
+                }
+            }
+        }
+        return Either.left(servicesAll);
+    }
 
-	public Either<List<Service>, StorageOperationStatus> getCertifiedServicesWithDistStatus(Set<DistributionStatusEnum> distStatus) {
-		Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
-		propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
+    public void rollback() {
+        titanDao.rollback();
+    }
 
-		return getServicesWithDistStatus(distStatus, propertiesToMatch);
-	}
+    public StorageOperationStatus addDeploymentArtifactsToInstance(String componentId, ComponentInstance componentInstance, Map<String, ArtifactDefinition> finalDeploymentArtifacts) {
+        Map<String, ArtifactDataDefinition> instDeplArtifacts = finalDeploymentArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
 
-	public Either<List<Service>, StorageOperationStatus> getServicesWithDistStatus(Set<DistributionStatusEnum> distStatus, Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
+        return nodeTemplateOperation.addDeploymentArtifactsToInstance(componentId, componentInstance.getUniqueId(), instDeplArtifacts);
+    }
 
-		List<Service> servicesAll = new ArrayList<>();
+    public StorageOperationStatus addInformationalArtifactsToInstance(String componentId, ComponentInstance componentInstance, Map<String, ArtifactDefinition> artifacts) {
+        StorageOperationStatus status = StorageOperationStatus.OK;
+        if (MapUtils.isNotEmpty(artifacts)) {
+            Map<String, ArtifactDataDefinition> instDeplArtifacts = artifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
+            status = nodeTemplateOperation.addInformationalArtifactsToInstance(componentId, componentInstance.getUniqueId(), instDeplArtifacts);
+        }
+        return status;
+    }
 
-		Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
-		Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
+    public StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId) {
+        return nodeTemplateOperation.generateCustomizationUUIDOnInstance(componentId, instanceId);
+    }
 
-		if (additionalPropertiesToMatch != null && !additionalPropertiesToMatch.isEmpty()) {
-			propertiesToMatch.putAll(additionalPropertiesToMatch);
-		}
+    public StorageOperationStatus generateCustomizationUUIDOnInstanceGroup(String componentId, String instanceId, List<String> groupInstances) {
+        return nodeTemplateOperation.generateCustomizationUUIDOnInstanceGroup(componentId, instanceId, groupInstances);
+    }
 
-		propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
+    /*
+     * adds property to a resource
+     * @warn this method has SIDE EFFECT on ownerId ,use it with caution
+     * */
+    public Either<PropertyDefinition, StorageOperationStatus> addPropertyToResource(String propertyName, PropertyDefinition newPropertyDefinition, Resource resource) {
 
-		propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+        Either<PropertyDefinition, StorageOperationStatus> result = null;
+        Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
+        newPropertyDefinition.setName(propertyName);
+        StorageOperationStatus status = getToscaElementOperation(resource).addToscaDataToToscaElement(resource.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, newPropertyDefinition, JsonPresentationFields.NAME);
+        if (status != StorageOperationStatus.OK) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, propertyName, resource.getName(), status);
+            result = Either.right(status);
+        }
+        if (result == null) {
+            ComponentParametersView filter = new ComponentParametersView(true);
+            filter.setIgnoreProperties(false);
+            getUpdatedComponentRes = getToscaElement(resource.getUniqueId(), filter);
+            if (getUpdatedComponentRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, resource.getUniqueId(), getUpdatedComponentRes.right().value());
+                result = Either.right(status);
+            }
+        }
+        if (result == null) {
+            PropertyDefinition newProperty = null;
+            List<PropertyDefinition> properties = ((Resource) getUpdatedComponentRes.left().value()).getProperties();
+            if (CollectionUtils.isNotEmpty(properties)) {
+                Optional<PropertyDefinition> newPropertyOptional = properties.stream().filter(p -> p.getName().equals(propertyName)).findAny();
+                if (newPropertyOptional.isPresent()) {
+                    newProperty = newPropertyOptional.get();
+                }
+            }
+            if (newProperty == null) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS, propertyName, resource.getUniqueId(), StorageOperationStatus.NOT_FOUND);
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+            } else {
+                result = Either.left(newProperty);
+            }
+        }
+        return result;
+    }
 
-		if (distStatus != null && !distStatus.isEmpty()) {
-			for (DistributionStatusEnum state : distStatus) {
-				propertiesToMatch.put(GraphPropertyEnum.DISTRIBUTION_STATUS, state.name());
-				Either<List<Service>, StorageOperationStatus> fetchServicesByCriteria = fetchServicesByCriteria(servicesAll, propertiesToMatch, propertiesNotToMatch);
-				if (fetchServicesByCriteria.isRight()) {
-					return fetchServicesByCriteria;
-				} else {
-					servicesAll = fetchServicesByCriteria.left().value();
-				}
-			}
-			return Either.left(servicesAll);
-		} else {
-			return fetchServicesByCriteria(servicesAll, propertiesToMatch, propertiesNotToMatch);
-		}
-	}
+    public StorageOperationStatus deletePropertyOfResource(Resource resource, String propertyName) {
+        return getToscaElementOperation(resource).deleteToscaDataElement(resource.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, propertyName, JsonPresentationFields.NAME);
+    }
 
-	private Either<List<Service>, StorageOperationStatus> fetchServicesByCriteria(List<Service> servicesAll, Map<GraphPropertyEnum, Object> propertiesToMatch, Map<GraphPropertyEnum, Object> propertiesNotToMatch) {
-		Either<List<GraphVertex>, TitanOperationStatus> getRes = titanDao.getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
-		if (getRes.isRight()) {
-			if (getRes.right().value() != TitanOperationStatus.NOT_FOUND) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch certified services by match properties {} not match properties {} . Status is {}. ", propertiesToMatch, propertiesNotToMatch, getRes.right().value());
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getRes.right().value()));
-			}
-		} else {
-			for (GraphVertex vertex : getRes.left().value()) {
-				// Either<Component, StorageOperationStatus> getServiceRes = getToscaElementByOperation(vertex);
-				Either<ToscaElement, StorageOperationStatus> getServiceRes = topologyTemplateOperation.getLightComponent(vertex, ComponentTypeEnum.SERVICE, new ComponentParametersView(true));
+    public StorageOperationStatus deleteAttributeOfResource(Component component, String attributeName) {
+        return getToscaElementOperation(component).deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, attributeName, JsonPresentationFields.NAME);
+    }
 
-				if (getServiceRes.isRight()) {
-					CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch certified service {}. Status is {}. ", vertex.getJsonMetadataField(JsonPresentationFields.NAME), getServiceRes.right().value());
-					return Either.right(getServiceRes.right().value());
-				} else {
-					servicesAll.add(ModelConverter.convertFromToscaElement(getServiceRes.left().value()));
-				}
-			}
-		}
-		return Either.left(servicesAll);
-	}
+    public StorageOperationStatus deleteInputOfResource(Component resource, String inputName) {
+        return getToscaElementOperation(resource).deleteToscaDataElement(resource.getUniqueId(), EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputName, JsonPresentationFields.NAME);
+    }
 
-	public void rollback() {
-		titanDao.rollback();
-	}
+    public Either<PropertyDefinition, StorageOperationStatus> updatePropertyOfResource(Resource resource, PropertyDefinition newPropertyDefinition) {
 
-	public StorageOperationStatus addDeploymentArtifactsToInstance(String componentId, ComponentInstance componentInstance, Map<String, ArtifactDefinition> finalDeploymentArtifacts) {
-		Map<String, ArtifactDataDefinition> instDeplArtifacts = finalDeploymentArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
+        Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
+        Either<PropertyDefinition, StorageOperationStatus> result = null;
+        StorageOperationStatus status = getToscaElementOperation(resource).updateToscaDataOfToscaElement(resource.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, newPropertyDefinition, JsonPresentationFields.NAME);
+        if (status != StorageOperationStatus.OK) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, newPropertyDefinition.getName(), resource.getName(), status);
+            result = Either.right(status);
+        }
+        if (result == null) {
+            ComponentParametersView filter = new ComponentParametersView(true);
+            filter.setIgnoreProperties(false);
+            getUpdatedComponentRes = getToscaElement(resource.getUniqueId(), filter);
+            if (getUpdatedComponentRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, resource.getUniqueId(), getUpdatedComponentRes.right().value());
+                result = Either.right(status);
+            }
+        }
+        if (result == null) {
+            Optional<PropertyDefinition> newProperty = ((Resource) getUpdatedComponentRes.left().value()).getProperties().stream().filter(p -> p.getName().equals(newPropertyDefinition.getName())).findAny();
+            if (newProperty.isPresent()) {
+                result = Either.left(newProperty.get());
+            } else {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS, newPropertyDefinition.getName(), resource.getUniqueId(), StorageOperationStatus.NOT_FOUND);
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+            }
+        }
+        return result;
+    }
 
-		return nodeTemplateOperation.addDeploymentArtifactsToInstance(componentId, componentInstance.getUniqueId(), instDeplArtifacts);
-	}
+    public Either<PropertyDefinition, StorageOperationStatus> addAttributeOfResource(Component component, PropertyDefinition newAttributeDef) {
 
-	public StorageOperationStatus addInformationalArtifactsToInstance(String componentId, ComponentInstance componentInstance, Map<String, ArtifactDefinition> artifacts) {
-		StorageOperationStatus status = StorageOperationStatus.OK;
-		if (MapUtils.isNotEmpty(artifacts)) {
-			Map<String, ArtifactDataDefinition> instDeplArtifacts = artifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
-			status = nodeTemplateOperation.addInformationalArtifactsToInstance(componentId, componentInstance.getUniqueId(), instDeplArtifacts);
-		}
-		return status;
-	}
+        Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
+        Either<PropertyDefinition, StorageOperationStatus> result = null;
+        if (newAttributeDef.getUniqueId() == null || newAttributeDef.getUniqueId().isEmpty()) {
+            String attUniqueId = UniqueIdBuilder.buildAttributeUid(component.getUniqueId(), newAttributeDef.getName());
+            newAttributeDef.setUniqueId(attUniqueId);
+        }
 
-	public StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId) {
-		return nodeTemplateOperation.generateCustomizationUUIDOnInstance(componentId, instanceId);
-	}
+        StorageOperationStatus status = getToscaElementOperation(component).addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef, JsonPresentationFields.NAME);
+        if (status != StorageOperationStatus.OK) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(), component.getName(), status);
+            result = Either.right(status);
+        }
+        if (result == null) {
+            ComponentParametersView filter = new ComponentParametersView(true);
+            filter.setIgnoreAttributesFrom(false);
+            getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
+            if (getUpdatedComponentRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(), getUpdatedComponentRes.right().value());
+                result = Either.right(status);
+            }
+        }
+        if (result == null) {
+            Optional<PropertyDefinition> newAttribute = ((Resource) getUpdatedComponentRes.left().value()).getAttributes().stream().filter(p -> p.getName().equals(newAttributeDef.getName())).findAny();
+            if (newAttribute.isPresent()) {
+                result = Either.left(newAttribute.get());
+            } else {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+            }
+        }
+        return result;
+    }
 
-	public StorageOperationStatus generateCustomizationUUIDOnInstanceGroup(String componentId, String instanceId, List<String> groupInstances) {
-		return nodeTemplateOperation.generateCustomizationUUIDOnInstanceGroup(componentId, instanceId, groupInstances);
-	}
+    public Either<PropertyDefinition, StorageOperationStatus> updateAttributeOfResource(Component component, PropertyDefinition newAttributeDef) {
 
-	/*
-	* adds property to a resource
-	* @warn this method has SIDE EFFECT on ownerId ,use it with caution
-	* */
-	public Either<PropertyDefinition, StorageOperationStatus> addPropertyToResource(String propertyName, PropertyDefinition newPropertyDefinition, Resource resource) {
+        Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
+        Either<PropertyDefinition, StorageOperationStatus> result = null;
+        StorageOperationStatus status = getToscaElementOperation(component).updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef, JsonPresentationFields.NAME);
+        if (status != StorageOperationStatus.OK) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(), component.getName(), status);
+            result = Either.right(status);
+        }
+        if (result == null) {
+            ComponentParametersView filter = new ComponentParametersView(true);
+            filter.setIgnoreAttributesFrom(false);
+            getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
+            if (getUpdatedComponentRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(), getUpdatedComponentRes.right().value());
+                result = Either.right(status);
+            }
+        }
+        if (result == null) {
+            Optional<PropertyDefinition> newProperty = ((Resource) getUpdatedComponentRes.left().value()).getAttributes().stream().filter(p -> p.getName().equals(newAttributeDef.getName())).findAny();
+            if (newProperty.isPresent()) {
+                result = Either.left(newProperty.get());
+            } else {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+            }
+        }
+        return result;
+    }
 
-		Either<PropertyDefinition, StorageOperationStatus> result = null;
-		Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
-		newPropertyDefinition.setName(propertyName);
-		StorageOperationStatus status = getToscaElementOperation(resource).addToscaDataToToscaElement(resource.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, newPropertyDefinition, JsonPresentationFields.NAME);
-		if (status != StorageOperationStatus.OK) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the property {} to the resource {}. Status is {}. ", propertyName, resource.getName(), status);
-			result = Either.right(status);
-		}
-		if (result == null) {
-			ComponentParametersView filter = new ComponentParametersView(true);
-			filter.setIgnoreProperties(false);
-			getUpdatedComponentRes = getToscaElement(resource.getUniqueId(), filter);
-			if (getUpdatedComponentRes.isRight()) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated resource {}. Status is {}. ", resource.getUniqueId(), getUpdatedComponentRes.right().value());
-				result = Either.right(status);
-			}
-		}
-		if (result == null) {
-			PropertyDefinition newProperty = null;
-			List<PropertyDefinition> properties = ((Resource) getUpdatedComponentRes.left().value()).getProperties();
-			if (CollectionUtils.isNotEmpty(properties)) {
-				Optional<PropertyDefinition> newPropertyOptional = properties.stream().filter(p -> p.getName().equals(propertyName)).findAny();
-				if (newPropertyOptional.isPresent()) {
-					newProperty = newPropertyOptional.get();
-				}
-			}
-			if (newProperty == null) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently added property {} on the resource {}. Status is {}. ", propertyName, resource.getUniqueId(), StorageOperationStatus.NOT_FOUND);
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-			} else {
-				result = Either.left(newProperty);
-			}
-		}
-		return result;
-	}
+    public Either<InputDefinition, StorageOperationStatus> updateInputOfComponent(Component component, InputDefinition newInputDefinition) {
 
-	public StorageOperationStatus deletePropertyOfResource(Resource resource, String propertyName) {
-		return getToscaElementOperation(resource).deleteToscaDataElement(resource.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, propertyName, JsonPresentationFields.NAME);
-	}
+        Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
+        Either<InputDefinition, StorageOperationStatus> result = null;
+        StorageOperationStatus status = getToscaElementOperation(component).updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, newInputDefinition, JsonPresentationFields.NAME);
+        if (status != StorageOperationStatus.OK) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the input {} to the component {}. Status is {}. ", newInputDefinition.getName(), component.getName(), status);
+            result = Either.right(status);
+        }
+        if (result == null) {
+            ComponentParametersView filter = new ComponentParametersView(true);
+            filter.setIgnoreInputs(false);
+            getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
+            if (getUpdatedComponentRes.isRight()) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(), getUpdatedComponentRes.right().value());
+                result = Either.right(status);
+            }
+        }
+        if (result == null) {
+            Optional<InputDefinition> updatedInput = getUpdatedComponentRes.left().value().getInputs().stream().filter(p -> p.getName().equals(newInputDefinition.getName())).findAny();
+            if (updatedInput.isPresent()) {
+                result = Either.left(updatedInput.get());
+            } else {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently updated inputs {} on the resource {}. Status is {}. ", newInputDefinition.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+            }
+        }
+        return result;
+    }
 
-	public StorageOperationStatus deleteAttributeOfResource(Component component, String attributeName) {
-		return getToscaElementOperation(component).deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, attributeName, JsonPresentationFields.NAME);
-	}
+    /**
+     * method - ename the group instances after referenced container name renamed flow - VF rename -(triggers)-> Group rename
+     *
+     * @param containerComponent  - container such as service
+     * @param componentInstance   - context component
+     * @param componentInstanceId - id
+     * @return - successfull/failed status
+     **/
+    public Either<StorageOperationStatus, StorageOperationStatus> cleanAndAddGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, String componentInstanceId) {
+        String uniqueId = componentInstance.getUniqueId();
+        StorageOperationStatus status = nodeTemplateOperation.deleteToscaDataDeepElementsBlockOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, uniqueId);
+        if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete group instances for container {}. error {] ", componentInstanceId, status);
+            return Either.right(status);
+        }
+        if (componentInstance.getGroupInstances() != null) {
+            status = addGroupInstancesToComponentInstance(containerComponent, componentInstance, componentInstance.getGroupInstances());
+            if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add group instances for container {}. error {] ", componentInstanceId, status);
+                return Either.right(status);
+            }
+        }
+        return Either.left(status);
+    }
 
-	public StorageOperationStatus deleteInputOfResource(Component resource, String inputName) {
-		return getToscaElementOperation(resource).deleteToscaDataElement(resource.getUniqueId(), EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputName, JsonPresentationFields.NAME);
-	}
+    public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupDefinition> groups, Map<String, List<ArtifactDefinition>> groupInstancesArtifacts) {
+        return nodeTemplateOperation.addGroupInstancesToComponentInstance(containerComponent, componentInstance, groups, groupInstancesArtifacts);
+    }
 
-	public Either<PropertyDefinition, StorageOperationStatus> updatePropertyOfResource(Resource resource, PropertyDefinition newPropertyDefinition) {
+    public Either<List<GroupDefinition>, StorageOperationStatus> updateGroupsOnComponent(Component component, List<GroupDataDefinition> updatedGroups) {
+        return groupsOperation.updateGroups(component, updatedGroups, true);
+    }
 
-		Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
-		Either<PropertyDefinition, StorageOperationStatus> result = null;
-		StorageOperationStatus status = getToscaElementOperation(resource).updateToscaDataOfToscaElement(resource.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, newPropertyDefinition, JsonPresentationFields.NAME);
-		if (status != StorageOperationStatus.OK) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the property {} to the resource {}. Status is {}. ", newPropertyDefinition.getName(), resource.getName(), status);
-			result = Either.right(status);
-		}
-		if (result == null) {
-			ComponentParametersView filter = new ComponentParametersView(true);
-			filter.setIgnoreProperties(false);
-			getUpdatedComponentRes = getToscaElement(resource.getUniqueId(), filter);
-			if (getUpdatedComponentRes.isRight()) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated resource {}. Status is {}. ", resource.getUniqueId(), getUpdatedComponentRes.right().value());
-				result = Either.right(status);
-			}
-		}
-		if (result == null) {
-			Optional<PropertyDefinition> newProperty = ((Resource) getUpdatedComponentRes.left().value()).getProperties().stream().filter(p -> p.getName().equals(newPropertyDefinition.getName())).findAny();
-			if (newProperty.isPresent()) {
-				result = Either.left(newProperty.get());
-			} else {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently added property {} on the resource {}. Status is {}. ", newPropertyDefinition.getName(), resource.getUniqueId(), StorageOperationStatus.NOT_FOUND);
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-			}
-		}
-		return result;
-	}
+    public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstancesOnComponent(Component component, String instanceId, List<GroupInstance> updatedGroupInstances) {
+        return groupsOperation.updateGroupInstances(component, instanceId, updatedGroupInstances);
+    }
 
-	public Either<PropertyDefinition, StorageOperationStatus> addAttributeOfResource(Component component, PropertyDefinition newAttributeDef) {
+    public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupInstance> groupInstances) {
+        return nodeTemplateOperation.addGroupInstancesToComponentInstance(containerComponent, componentInstance, groupInstances);
+    }
 
-		Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
-		Either<PropertyDefinition, StorageOperationStatus> result = null;
-		if (newAttributeDef.getUniqueId() == null || newAttributeDef.getUniqueId().isEmpty()) {
-			String attUniqueId = UniqueIdBuilder.buildAttributeUid(component.getUniqueId(), newAttributeDef.getName());
-			newAttributeDef.setUniqueId(attUniqueId);
-		}
+    public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance, Map<String, ArtifactDefinition> deploymentArtifacts) {
+        return nodeTemplateOperation.addDeploymentArtifactsToComponentInstance(containerComponent, componentInstance, deploymentArtifacts);
+    }
 
-		StorageOperationStatus status = getToscaElementOperation(component).addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef, JsonPresentationFields.NAME);
-		if (status != StorageOperationStatus.OK) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the property {} to the resource {}. Status is {}. ", newAttributeDef.getName(), component.getName(), status);
-			result = Either.right(status);
-		}
-		if (result == null) {
-			ComponentParametersView filter = new ComponentParametersView(true);
-			filter.setIgnoreAttributesFrom(false);
-			getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
-			if (getUpdatedComponentRes.isRight()) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated resource {}. Status is {}. ", component.getUniqueId(), getUpdatedComponentRes.right().value());
-				result = Either.right(status);
-			}
-		}
-		if (result == null) {
-			Optional<PropertyDefinition> newAttribute = ((Resource) getUpdatedComponentRes.left().value()).getAttributes().stream().filter(p -> p.getName().equals(newAttributeDef.getName())).findAny();
-			if (newAttribute.isPresent()) {
-				result = Either.left(newAttribute.get());
-			} else {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently added property {} on the resource {}. Status is {}. ", newAttributeDef.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-			}
-		}
-		return result;
-	}
+    public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
+        return nodeTemplateOperation.updateComponentInstanceProperty(containerComponent, componentInstanceId, property);
+    }
 
-	public Either<PropertyDefinition, StorageOperationStatus> updateAttributeOfResource(Component component, PropertyDefinition newAttributeDef) {
+    public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId, List<ComponentInstanceProperty> properties) {
+        return nodeTemplateOperation.updateComponentInstanceProperties(containerComponent, componentInstanceId, properties);
+    }
 
-		Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
-		Either<PropertyDefinition, StorageOperationStatus> result = null;
-		StorageOperationStatus status = getToscaElementOperation(component).updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef, JsonPresentationFields.NAME);
-		if (status != StorageOperationStatus.OK) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the property {} to the resource {}. Status is {}. ", newAttributeDef.getName(), component.getName(), status);
-			result = Either.right(status);
-		}
-		if (result == null) {
-			ComponentParametersView filter = new ComponentParametersView(true);
-			filter.setIgnoreAttributesFrom(false);
-			getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
-			if (getUpdatedComponentRes.isRight()) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated resource {}. Status is {}. ", component.getUniqueId(), getUpdatedComponentRes.right().value());
-				result = Either.right(status);
-			}
-		}
-		if (result == null) {
-			Optional<PropertyDefinition> newProperty = ((Resource) getUpdatedComponentRes.left().value()).getAttributes().stream().filter(p -> p.getName().equals(newAttributeDef.getName())).findAny();
-			if (newProperty.isPresent()) {
-				result = Either.left(newProperty.get());
-			} else {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently added property {} on the resource {}. Status is {}. ", newAttributeDef.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-			}
-		}
-		return result;
-	}
 
-	public Either<InputDefinition, StorageOperationStatus> updateInputOfComponent(Component component, InputDefinition newInputDefinition) {
+    public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
+        return nodeTemplateOperation.addComponentInstanceProperty(containerComponent, componentInstanceId, property);
+    }
 
-		Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
-		Either<InputDefinition, StorageOperationStatus> result = null;
-		StorageOperationStatus status = getToscaElementOperation(component).updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, newInputDefinition, JsonPresentationFields.NAME);
-		if (status != StorageOperationStatus.OK) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the input {} to the component {}. Status is {}. ", newInputDefinition.getName(), component.getName(), status);
-			result = Either.right(status);
-		}
-		if (result == null) {
-			ComponentParametersView filter = new ComponentParametersView(true);
-			filter.setIgnoreInputs(false);
-			getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
-			if (getUpdatedComponentRes.isRight()) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated resource {}. Status is {}. ", component.getUniqueId(), getUpdatedComponentRes.right().value());
-				result = Either.right(status);
-			}
-		}
-		if (result == null) {
-			Optional<InputDefinition> updatedInput = getUpdatedComponentRes.left().value().getInputs().stream().filter(p -> p.getName().equals(newInputDefinition.getName())).findAny();
-			if (updatedInput.isPresent()) {
-				result = Either.left(updatedInput.get());
-			} else {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently updated inputs {} on the resource {}. Status is {}. ", newInputDefinition.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-			}
-		}
-		return result;
-	}
+    public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
+        return nodeTemplateOperation.updateComponentInstanceInput(containerComponent, componentInstanceId, property);
+    }
 
-	/**
-	 * method - ename the group instances after referenced container name renamed flow - VF rename -(triggers)-> Group rename
-	 *
-	 * @param containerComponent
-	 *            - container such as service
-	 * @param componentInstance
-	 *            - context component
-	 * @param componentInstanceId
-	 *            - id
-	 *
-	 * @return - successfull/failed status
-	 **/
-	public Either<StorageOperationStatus, StorageOperationStatus> cleanAndAddGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, String componentInstanceId) {
-		String uniqueId = componentInstance.getUniqueId();
-		StorageOperationStatus status = nodeTemplateOperation.deleteToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, uniqueId);
-		if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-			CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete group instances for container {}. error {] ", componentInstanceId, status);
-			return Either.right(status);
-		}
-		if (componentInstance.getGroupInstances() != null) {
-			status = addGroupInstancesToComponentInstance(containerComponent, componentInstance, componentInstance.getGroupInstances());
-			if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
-				CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add group instances for container {}. error {] ", componentInstanceId, status);
-				return Either.right(status);
-			}
-		}
-		return Either.left(status);
-	}
+    public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceInput> instanceInputs) {
+        return nodeTemplateOperation.updateComponentInstanceInputs(containerComponent, componentInstanceId, instanceInputs);
+    }
 
-	public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupDefinition> groups, Map<String, List<ArtifactDefinition>> groupInstancesArtifacts) {
-		return nodeTemplateOperation.addGroupInstancesToComponentInstance(containerComponent, componentInstance, groups, groupInstancesArtifacts);
-	}
+    public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
+        return nodeTemplateOperation.addComponentInstanceInput(containerComponent, componentInstanceId, property);
+    }
 
-	public Either<List<GroupDefinition>, StorageOperationStatus> updateGroupsOnComponent(Component component, List<GroupDataDefinition> updatedGroups) {
-		return groupsOperation.updateGroups(component, updatedGroups);
-	}
+    public void setNodeTypeOperation(NodeTypeOperation nodeTypeOperation) {
+        this.nodeTypeOperation = nodeTypeOperation;
+    }
 
-	public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstancesOnComponent(Component component, ComponentTypeEnum componentType, String instanceId, List<GroupInstance> updatedGroupInstances) {
-		return groupsOperation.updateGroupInstances(component, instanceId, updatedGroupInstances);
-	}
+    public void setTopologyTemplateOperation(TopologyTemplateOperation topologyTemplateOperation) {
+        this.topologyTemplateOperation = topologyTemplateOperation;
+    }
 
-	public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupInstance> groupInstances) {
-		return nodeTemplateOperation.addGroupInstancesToComponentInstance(containerComponent, componentInstance, groupInstances);
-	}
+    public StorageOperationStatus deleteComponentInstanceInputsFromTopologyTemplate(Component containerComponent, List<InputDefinition> inputsToDelete) {
+        return topologyTemplateOperation.deleteToscaDataElements(containerComponent.getUniqueId(), EdgeLabelEnum.INPUTS, inputsToDelete.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList()));
+    }
 
-	public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance, Map<String, ArtifactDefinition> deploymentArtifacts) {
-		return nodeTemplateOperation.addDeploymentArtifactsToComponentInstance(containerComponent, componentInstance, deploymentArtifacts);
-	}
+    public StorageOperationStatus updateComponentInstanceCapabiltyProperty(Component containerComponent, String componentInstanceUniqueId, String capabilityUniqueId, ComponentInstanceProperty property) {
+        return nodeTemplateOperation.updateComponentInstanceCapabilityProperty(containerComponent, componentInstanceUniqueId, capabilityUniqueId, property);
+    }
 
-	public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
-		return nodeTemplateOperation.updateComponentInstanceProperty(containerComponent, componentInstanceId, property);
-	}
+    public StorageOperationStatus updateComponentInstanceCapabilityProperties(Component containerComponent, String componentInstanceUniqueId) {
+        return convertComponentInstanceProperties(containerComponent, componentInstanceUniqueId)
+                .map(instanceCapProps -> topologyTemplateOperation.updateComponentInstanceCapabilityProperties(containerComponent, componentInstanceUniqueId, instanceCapProps))
+                .orElse(StorageOperationStatus.NOT_FOUND);
+    }
 
-	public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId, List<ComponentInstanceProperty> properties) {
-		return nodeTemplateOperation.updateComponentInstanceProperties(containerComponent, componentInstanceId, properties);
-	}
+    public StorageOperationStatus updateComponentCalculatedCapabilitiesProperties(Component containerComponent) {
+        Map<String, MapCapabilityProperty> MapCapabilityPropertyMap = convertComponentCapabilitiesProperties(containerComponent);
+        return nodeTemplateOperation.overrideComponentCapabilitiesProperties(containerComponent, MapCapabilityPropertyMap);
+    }
 
+    public StorageOperationStatus deleteAllCalculatedCapabilitiesRequirements(String topologyTemplateId) {
+        StorageOperationStatus status = topologyTemplateOperation.removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES);
+        if (status == StorageOperationStatus.OK) {
+            status = topologyTemplateOperation.removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS);
+        }
+        if (status == StorageOperationStatus.OK) {
+            status = topologyTemplateOperation.removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES);
+        }
+        return status;
+    }
 
-	public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
-		return nodeTemplateOperation.addComponentInstanceProperty(containerComponent, componentInstanceId, property);
-	}
+    public Either<Component, StorageOperationStatus> shouldUpgradeToLatestDerived(Resource clonedResource) {
+        String componentId = clonedResource.getUniqueId();
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
 
-	public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
-		return nodeTemplateOperation.updateComponentInstanceInput(containerComponent, componentInstanceId, property);
-	}
+        }
+        GraphVertex nodeTypeV = getVertexEither.left().value();
 
-	public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceInput> instanceInputs) {
-		return nodeTemplateOperation.updateComponentInstanceInputs(containerComponent, componentInstanceId, instanceInputs);
-	}
+        ToscaElement toscaElementToUpdate = ModelConverter.convertToToscaElement(clonedResource);
 
-	public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
-		return nodeTemplateOperation.addComponentInstanceInput(containerComponent, componentInstanceId, property);
-	}
+        Either<ToscaElement, StorageOperationStatus> shouldUpdateDerivedVersion = nodeTypeOperation.shouldUpdateDerivedVersion(toscaElementToUpdate, nodeTypeV);
+        if (shouldUpdateDerivedVersion.isRight() && StorageOperationStatus.OK != shouldUpdateDerivedVersion.right().value()) {
+            log.debug("Failed to update derived version for node type {} derived {}, error: {}", componentId, clonedResource.getDerivedFrom().get(0), shouldUpdateDerivedVersion.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+        }
+        if (shouldUpdateDerivedVersion.isLeft()) {
+            return Either.left(ModelConverter.convertFromToscaElement(shouldUpdateDerivedVersion.left().value()));
+        }
+        return Either.left(clonedResource);
+    }
 
-	public void setNodeTypeOperation(NodeTypeOperation nodeTypeOperation) {
-		this.nodeTypeOperation = nodeTypeOperation;
-	}
+    /**
+     * Returns list of ComponentInstanceProperty belonging to component instance capability specified by name, type and ownerId
+     */
+    public Either<List<ComponentInstanceProperty>, StorageOperationStatus> getComponentInstanceCapabilityProperties(String componentId, String instanceId, String capabilityName, String capabilityType, String ownerId) {
+        return topologyTemplateOperation.getComponentInstanceCapabilityProperties(componentId, instanceId, capabilityName, capabilityType, ownerId);
+    }
 
-	public void setTopologyTemplateOperation(TopologyTemplateOperation topologyTemplateOperation) {
-		this.topologyTemplateOperation = topologyTemplateOperation;
-	}
+    private Map<String, MapCapabilityProperty> convertComponentCapabilitiesProperties(Component currComponent) {
+        Map<String, MapCapabilityProperty> map = ModelConverter.extractCapabilityPropertiesFromGroups(currComponent.getGroups(), true);
+        map.putAll(ModelConverter.extractCapabilityProperteisFromInstances(currComponent.getComponentInstances(), true));
+        return map;
+    }
 
-	public StorageOperationStatus deleteComponentInstanceInputsFromTopologyTemplate(Component containerComponent, ComponentTypeEnum componentType, List<InputDefinition> inputsToDelete) {
-		return topologyTemplateOperation.deleteToscaDataElements(containerComponent.getUniqueId(), EdgeLabelEnum.INPUTS, inputsToDelete.stream().map(i -> i.getName()).collect(Collectors.toList()));
-	}
+    private Optional<MapCapabilityProperty> convertComponentInstanceProperties(Component component, String instanceId) {
+        return component.fetchInstanceById(instanceId)
+                .map(ci -> ModelConverter.convertToMapOfMapCapabiltyProperties(ci.getCapabilities(), instanceId));
+    }
 
-	public StorageOperationStatus updateComponentInstanceCapabiltyProperty(Component containerComponent, String componentInstanceUniqueId, String capabilityUniqueId, ComponentInstanceProperty property) {
-		return nodeTemplateOperation.updateComponentInstanceCapabilityProperty(containerComponent, componentInstanceUniqueId, capabilityUniqueId, property);
-	}
+    public Either<PolicyDefinition, StorageOperationStatus> associatePolicyToComponent(String componentId, PolicyDefinition policyDefinition, int counter) {
+        Either<PolicyDefinition, StorageOperationStatus> result = null;
+        Either<GraphVertex, TitanOperationStatus> getVertexEither;
+        getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
+        if (getVertexEither.isRight()) {
+            log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+        } else {
+            if (getVertexEither.left().value().getLabel() != VertexTypeEnum.TOPOLOGY_TEMPLATE) {
+                log.error("Policy association to component of Tosca type {} is not allowed. ", getVertexEither.left().value().getLabel());
+                result = Either.right(StorageOperationStatus.BAD_REQUEST);
+            }
+        }
+        if (result == null) {
+            StorageOperationStatus status = topologyTemplateOperation.addPolicyToToscaElement(getVertexEither.left().value(), policyDefinition, counter);
+            if (status != StorageOperationStatus.OK) {
+                return Either.right(status);
+            }
+        }
+        if (result == null) {
+            result = Either.left(policyDefinition);
+        }
+        return result;
+    }
 
-	public StorageOperationStatus updateComponentInstanceCapabilityProperties(Component containerComponent, String componentInstanceUniqueId) {
-		return convertComponentInstanceProperties(containerComponent, componentInstanceUniqueId)
-				.map(instanceCapProps -> topologyTemplateOperation.updateComponentInstanceCapabilityProperties(containerComponent, componentInstanceUniqueId, instanceCapProps))
-				.orElse(StorageOperationStatus.NOT_FOUND);
-	}
+    public StorageOperationStatus associatePoliciesToComponent(String componentId, List<PolicyDefinition> policies) {
+        log.debug("#associatePoliciesToComponent - associating policies for component {}.", componentId);
+        return titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata)
+                .either(containerVertex -> topologyTemplateOperation.addPoliciesToToscaElement(containerVertex, policies),
+                        DaoStatusConverter::convertTitanStatusToStorageStatus);
+    }
 
-	public StorageOperationStatus updateComponentCalculatedCapabilitiesProperties(Component containerComponent) {
-		Map<String, MapCapabiltyProperty> mapCapabiltyPropertyMap = convertComponentCapabilitiesProperties(containerComponent);
-		return nodeTemplateOperation.overrideComponentCapabilitiesProperties(containerComponent, mapCapabiltyPropertyMap);
-	}
+    public Either<PolicyDefinition, StorageOperationStatus> updatePolicyOfComponent(String componentId, PolicyDefinition policyDefinition) {
+        Either<PolicyDefinition, StorageOperationStatus> result = null;
+        Either<GraphVertex, TitanOperationStatus> getVertexEither;
+        getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+        }
+        if (result == null) {
+            StorageOperationStatus status = topologyTemplateOperation.updatePolicyOfToscaElement(getVertexEither.left().value(), policyDefinition);
+            if (status != StorageOperationStatus.OK) {
+                return Either.right(status);
+            }
+        }
+        if (result == null) {
+            result = Either.left(policyDefinition);
+        }
+        return result;
+    }
 
-	public StorageOperationStatus deleteAllCalculatedCapabilitiesRequirements(String topologyTemplateId) {
-		StorageOperationStatus status = topologyTemplateOperation.removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES);
-		if (status == StorageOperationStatus.OK) {
-			status = topologyTemplateOperation.removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS);
-		}
-		if(status == StorageOperationStatus.OK){
-			status = topologyTemplateOperation.removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES);
-		}
-		return status;
-	}
+    public StorageOperationStatus updatePoliciesOfComponent(String componentId, List<PolicyDefinition> policyDefinition) {
+        log.debug("#updatePoliciesOfComponent - updating policies for component {}", componentId);
+        return titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus)
+                .either(containerVertex -> topologyTemplateOperation.updatePoliciesOfToscaElement(containerVertex, policyDefinition),
+                        err -> err);
+    }
 
-	public Either<Component, StorageOperationStatus> shouldUpgradeToLatestDerived(Resource clonedResource) {
-		String componentId = clonedResource.getUniqueId();
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.debug("Couldn't fetch component with and unique id {}, error: {}", componentId, getVertexEither.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
+    public StorageOperationStatus removePolicyFromComponent(String componentId, String policyId) {
+        StorageOperationStatus status = null;
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            status = DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value());
+        }
+        if (status == null) {
+            status = topologyTemplateOperation.removePolicyFromToscaElement(getVertexEither.left().value(), policyId);
+        }
+        return status;
+    }
 
-		}
-		GraphVertex nodeTypeV = getVertexEither.left().value();
-		
-		ToscaElement toscaElementToUpdate = ModelConverter.convertToToscaElement(clonedResource);
+    public boolean canAddGroups(String componentId) {
+        GraphVertex vertex = titanDao.getVertexById(componentId)
+                .left()
+                .on(this::onTitanError);
+        return topologyTemplateOperation.hasEdgeOfType(vertex, EdgeLabelEnum.GROUPS);
+    }
 
-		Either<ToscaElement, StorageOperationStatus> shouldUpdateDerivedVersion = nodeTypeOperation.shouldUpdateDerivedVersion(toscaElementToUpdate, nodeTypeV);
-		if ( shouldUpdateDerivedVersion.isRight() && StorageOperationStatus.OK != shouldUpdateDerivedVersion.right().value() ){
-			log.debug("Failed to update derived version for node type {} derived {}, error: {}", componentId, clonedResource.getDerivedFrom().get(0), shouldUpdateDerivedVersion.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
-		}
-		if ( shouldUpdateDerivedVersion.isLeft() ){
-			return Either.left(ModelConverter.convertFromToscaElement(shouldUpdateDerivedVersion.left().value()));
-		}
-		return Either.left(clonedResource);
-	}
-	/**
-	 * Returns list of ComponentInstanceProperty belonging to component instance capability specified by name, type and ownerId
-	 * @param componentId
-	 * @param instanceId
-	 * @param capabilityName
-	 * @param capabilityType
-	 * @param ownerId 
-	 * @return
-	 */
-	public Either<List<ComponentInstanceProperty>, StorageOperationStatus> getComponentInstanceCapabilityProperties(String componentId, String instanceId, String capabilityName, String capabilityType, String ownerId) {
-		return topologyTemplateOperation.getComponentInstanceCapabilityProperties(componentId, instanceId, capabilityName, capabilityType, ownerId);
-	}
+    GraphVertex onTitanError(TitanOperationStatus toe) {
+        throw new StorageException(
+                DaoStatusConverter.convertTitanStatusToStorageStatus(toe));
+    }
 
-	private Map<String, MapCapabiltyProperty> convertComponentCapabilitiesProperties(Component currComponent) {
-		return currComponent.getComponentInstances()
-				.stream()
-				.collect(Collectors.toMap(ComponentInstanceDataDefinition::getUniqueId,
-						ci -> ModelConverter.convertToMapOfMapCapabiltyProperties(ci.getCapabilities(), ci.getUniqueId(), true)));
-	}
+    public void updateNamesOfCalculatedCapabilitiesRequirements(String componentId){
+        topologyTemplateOperation
+                .updateNamesOfCalculatedCapabilitiesRequirements(componentId, getTopologyTemplate(componentId));
+    }
 
-	private Optional<MapCapabiltyProperty> convertComponentInstanceProperties(Component component, String instanceId) {
-		return component.fetchInstanceById(instanceId)
-				.map(ci -> ModelConverter.convertToMapOfMapCapabiltyProperties(ci.getCapabilities(),instanceId));
-	}
+    public void revertNamesOfCalculatedCapabilitiesRequirements(String componentId) {
+        topologyTemplateOperation
+                .revertNamesOfCalculatedCapabilitiesRequirements(componentId, getTopologyTemplate(componentId));
+    }
 
-	public Either<PolicyDefinition, StorageOperationStatus> associatePolicyToComponent(String componentId, PolicyDefinition policyDefinition, int counter) {
-		Either<PolicyDefinition, StorageOperationStatus> result = null;
-		Either<GraphVertex, TitanOperationStatus> getVertexEither;
-		getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
-		if (getVertexEither.isRight()) {
-			log.error("Couldn't fetch a component with and UniqueId {}, error: {}", componentId, getVertexEither.right().value());
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
-		} else {
-			if(getVertexEither.left().value().getLabel() != VertexTypeEnum.TOPOLOGY_TEMPLATE){
-				log.error("Policy association to component of Tosca type {} is not allowed. ", getVertexEither.left().value().getLabel());
-				result = Either.right(StorageOperationStatus.BAD_REQUEST);
-			}
-		}
-		if(result == null){
-			StorageOperationStatus status = topologyTemplateOperation.addPolicyToToscaElement(getVertexEither.left().value(), policyDefinition, counter);
-			if(status != StorageOperationStatus.OK){
-			 	return Either.right(status);
-			}
-		}
-		if(result == null){
-			result = Either.left(policyDefinition);
-		}
-		return result;
-	}
+    private TopologyTemplate getTopologyTemplate(String componentId) {
+        return (TopologyTemplate)topologyTemplateOperation
+                .getToscaElement(componentId, getFilterComponentWithCapProperties())
+                .left()
+                .on(this::throwStorageException);
+    }
 
-	public Either<PolicyDefinition, StorageOperationStatus> updatePolicyOfComponent(String componentId,	PolicyDefinition policyDefinition) {
-		Either<PolicyDefinition, StorageOperationStatus> result = null;
-		Either<GraphVertex, TitanOperationStatus> getVertexEither;
-		getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.error("Couldn't fetch a component with and UniqueId {}, error: {}", componentId, getVertexEither.right().value());
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value()));
-		}
-		if(result == null){
-			StorageOperationStatus status = topologyTemplateOperation.updatePolicyOfToscaElement(getVertexEither.left().value(), policyDefinition);
-			if(status != StorageOperationStatus.OK){
-				return Either.right(status);
-			}
-		}
-		if(result == null){
-			result = Either.left(policyDefinition);
-		}
-		return result;
-	}
+    private ComponentParametersView getFilterComponentWithCapProperties() {
+        ComponentParametersView filter = new ComponentParametersView();
+        filter.setIgnoreCapabiltyProperties(false);
+        return filter;
+    }
 
-	public StorageOperationStatus updatePoliciesOfComponent(String componentId, List<PolicyDefinition> policyDefinition) {
-		log.debug("#updatePoliciesOfComponent - updating policies for component {}", componentId);
-		return titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse)
-				.right()
-				.map(DaoStatusConverter::convertTitanStatusToStorageStatus)
-				.either(containerVertex -> topologyTemplateOperation.updatePoliciesOfToscaElement(containerVertex, policyDefinition),
-						err -> err);
-	}
+    private ToscaElement throwStorageException(StorageOperationStatus status) {
+        throw new StorageException(status);
+    }
 
-	public StorageOperationStatus removePolicyFromComponent(String componentId,	String policyId) {
-		StorageOperationStatus status = null;
-		Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
-		if (getVertexEither.isRight()) {
-			log.error("Couldn't fetch a component with and UniqueId {}, error: {}", componentId, getVertexEither.right().value());
-			status = DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexEither.right().value());
-		}
-		if(status == null){
-			status = topologyTemplateOperation.removePolicyFromToscaElement(getVertexEither.left().value(), policyId);
-		}
-		return status;
-	}
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/UpgradeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/UpgradeOperation.java
new file mode 100644
index 0000000..5faa6bb
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/UpgradeOperation.java
@@ -0,0 +1,225 @@
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.model.ComponentDependency;
+import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Component
+public class UpgradeOperation extends BaseOperation {
+    private static final Logger log = Logger.getLogger(UpgradeOperation.class.getName());
+
+    public Either<List<ComponentDependency>, StorageOperationStatus> getComponentDependencies(String componentId) {
+        Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(componentId);
+        if (vertexById.isRight()) {
+            log.debug("Failed to fetch vertex with id {} error {}", componentId, vertexById.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexById.right().value()));
+        }
+        List<ComponentDependency> dependencies = new ArrayList<>();
+
+        GraphVertex vertex = vertexById.left().value();
+
+        StorageOperationStatus status = fillDependenciesByVertex(componentId, dependencies, vertex);
+        if (status != StorageOperationStatus.OK) {
+            return Either.right(status);
+        }
+
+        GraphVertex vertexToStart = vertex;
+        Function<GraphVertex, Either<GraphVertex, TitanOperationStatus>> getNextElement = vertexP -> titanDao.getParentVertex(vertexP, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll);
+        status = handleVersionChain(componentId, dependencies, vertex, getNextElement);
+        if (status != StorageOperationStatus.OK) {
+            return Either.right(status);
+        }
+        vertex = vertexToStart;
+        getNextElement = vertexP -> titanDao.getChildVertex(vertexP, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll);
+        status = handleVersionChain(componentId, dependencies, vertex, getNextElement);
+
+        return status == StorageOperationStatus.OK ? Either.left(dependencies) : Either.right(status);
+    }
+
+    private StorageOperationStatus handleVersionChain(String componentId, List<ComponentDependency> dependencies, GraphVertex vertexToStart, Function<GraphVertex, Either<GraphVertex, TitanOperationStatus>> getNextElement) {
+
+        StorageOperationStatus status;
+        boolean nextInChain = true;
+        GraphVertex vertex = vertexToStart;
+        Either<GraphVertex, TitanOperationStatus> nextInChainV;
+        while (nextInChain) {
+            nextInChainV = getNextElement.apply(vertex);
+            if (nextInChainV.isRight()) {
+                nextInChain = false;
+            } else {
+                vertex = nextInChainV.left().value();
+                status = fillDependenciesByVertex(componentId, dependencies, vertex);
+                if (status != StorageOperationStatus.OK) {
+                    return status;
+                }
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
+
+    private StorageOperationStatus fillDependenciesByVertex(String componentId, List<ComponentDependency> dependencies, GraphVertex vertex) {
+        StorageOperationStatus status = StorageOperationStatus.OK;
+        if ( needToAddToDepenedency(vertex) ) {
+            ComponentDependency dependency = fillDataFromVertex(vertex, null, null);
+
+            List<EdgeLabelEnum> dependList = Arrays.asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF, EdgeLabelEnum.ALLOTTED_OF);
+            for (EdgeLabelEnum label : dependList) {
+                status = fillDependenciesByLabel(componentId, vertex, dependency, label);
+                if (status != StorageOperationStatus.OK) {
+                    log.debug("Failed to create dependencies for component {} and label {} status {}", componentId, label, status);
+                    break;
+                }
+            }
+            if (status == StorageOperationStatus.OK) {
+                dependencies.add(dependency);
+            }
+        }
+        return status;
+    }
+    private boolean needToAddToDepenedency(GraphVertex vertex){
+        Boolean isDeleted = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_DELETED);     
+        Boolean isArchived = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_ARCHIVED);
+        return ( isDeleted == Boolean.TRUE || isArchived == Boolean.TRUE) ? false : true;
+    }
+
+    private StorageOperationStatus fillDependenciesByLabel(String componentId, GraphVertex vertex, ComponentDependency dependency, EdgeLabelEnum label) {
+        Either<List<GraphVertex>, TitanOperationStatus> parentVertecies = titanDao.getParentVertecies(vertex, label, JsonParseFlagEnum.ParseAll);
+        if (parentVertecies.isRight() && parentVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
+            log.debug("Failed to fetch parent verticies by label INSTANCE_OF for vertex with id {} error {}", componentId, parentVertecies.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(parentVertecies.right().value());
+        }
+        if (parentVertecies.isLeft()) {
+            List<ComponentDependency> existIn = new ArrayList<>( );
+            parentVertecies.left().value().forEach(v -> handleHighestVersion(vertex, label, existIn, v) );
+            dependency.addDependencies(existIn);
+        }
+        return StorageOperationStatus.OK;
+    }
+
+    private void handleHighestVersion(GraphVertex vertexOrigin, EdgeLabelEnum label, List<ComponentDependency> exisIn, GraphVertex containerVertex) {
+        Boolean isHighest = (Boolean) containerVertex.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
+        if ( isHighest && needToAddToDepenedency(containerVertex) ) {  
+            TitanVertex titanVertex = containerVertex.getVertex();
+            Iterator<Edge> edges = titanVertex.edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
+            //verify that it is a last version - highest by version number
+            if ( edges == null || !edges.hasNext() ){
+                ComponentDependency container = fillDataFromVertex(containerVertex, vertexOrigin.getUniqueId(), label);
+                boolean addToDependency = true;
+                if (label == EdgeLabelEnum.ALLOTTED_OF) {
+                    //in case of not full allotted chain not add to dependency list
+                    addToDependency = findAllottedChain(containerVertex, container);
+                }
+                if ( addToDependency ){
+                    exisIn.add(container);
+                 }
+            }
+        }
+    }
+
+    private boolean findAllottedChain(GraphVertex vertex, ComponentDependency container) {
+        Either<List<GraphVertex>, TitanOperationStatus> parentVertecies = titanDao.getParentVertecies(vertex, EdgeLabelEnum.INSTANCE_OF, JsonParseFlagEnum.ParseAll);
+        if (parentVertecies.isLeft()) {
+            List<ComponentDependency> existIn = new ArrayList<>();
+            parentVertecies.left().value().forEach(v -> {
+                Boolean isHighest = (Boolean) v.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
+                if ( isHighest && needToAddToDepenedency(v) ) {
+                   TitanVertex titanVertex = v.getVertex();
+                   Iterator<Edge> edges = titanVertex.edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
+                   //verify that it is a last version - highest by version number
+                   if ( edges == null || !edges.hasNext() ){
+                       ComponentDependency parentContainer = fillDataFromVertex(v, vertex.getUniqueId(), EdgeLabelEnum.INSTANCE_OF);
+                       existIn.add(parentContainer);
+                   }
+                }
+            });
+            if ( !existIn.isEmpty() ){
+                container.setDependencies(existIn);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private ComponentDependency fillDataFromVertex(GraphVertex v, String originId, EdgeLabelEnum edgeLabel) {
+        ComponentDependency container = new ComponentDependency();
+        container.setName((String) v.getMetadataProperty(GraphPropertyEnum.NAME));
+        container.setVersion((String) v.getMetadataProperty(GraphPropertyEnum.VERSION));
+        container.setUniqueId(v.getUniqueId());
+        container.setType((String) v.getMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE));
+        container.setIcon((String) v.getJsonMetadataField(JsonPresentationFields.ICON));
+        container.setState((String) v.getMetadataProperty(GraphPropertyEnum.STATE));
+
+        if (edgeLabel == EdgeLabelEnum.PROXY_OF || edgeLabel == EdgeLabelEnum.ALLOTTED_OF) {
+            findInstanceNames(v, originId, edgeLabel, container);
+        }
+        return container;
+    }
+
+    private void findInstanceNames(GraphVertex v, String originId, EdgeLabelEnum edgeLabel, ComponentDependency container) {
+        Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) v.getJson();
+        CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
+        TitanVertex vertex = v.getVertex();
+        Iterator<Edge> edges = vertex.edges(Direction.OUT, edgeLabel.name());
+        while (edges != null && edges.hasNext()) {
+            Edge edge = edges.next();
+            TitanVertex inVertex = (TitanVertex) edge.inVertex();
+            String id = (String) titanDao.getProperty(inVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
+            if (id.equals(originId)) {
+                List<String> instanceOnEdge = (List<String>) titanDao.getProperty(edge, EdgePropertyEnum.INSTANCES);
+                Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
+
+                if (componentInstances != null) {
+                    List<String> ciNames = componentInstances
+                            .values()
+                            .stream()
+                            .filter(ci -> instanceOnEdge.contains(ci.getUniqueId()))
+                            .map(ComponentInstanceDataDefinition::getName)
+                            .collect(Collectors.toList());
+                    if (ciNames != null && !ciNames.isEmpty()) {
+                        container.setInstanceNames(ciNames);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    public List<String> getInstanceIdFromAllottedEdge(String resourceId, String serviceInvariantUUID) {
+      Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(resourceId);
+      if ( vertexById.isLeft() ){
+          GraphVertex vertexG = vertexById.left().value();
+          TitanVertex vertex = vertexG.getVertex();
+          Iterator<Edge> edges = vertex.edges(Direction.OUT, EdgeLabelEnum.ALLOTTED_OF.name());
+          while ( edges != null && edges.hasNext() ){
+              Edge edge = edges.next();
+              TitanVertex inVertex = (TitanVertex)edge.inVertex();
+              String vertexInInvUUID = (String) titanDao.getProperty(inVertex, GraphPropertyEnum.INVARIANT_UUID.getProperty());
+              if ( vertexInInvUUID.equals(serviceInvariantUUID) ){
+                  return (List<String>) titanDao.getProperty(edge, EdgePropertyEnum.INSTANCES) ;
+              }
+          }
+      }
+      return new ArrayList<>();
+    }
+
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/IdMapper.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/IdMapper.java
index 37c21e8..2c3c98e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/IdMapper.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/IdMapper.java
@@ -1,24 +1,23 @@
 package org.openecomp.sdc.be.model.jsontitan.utils;
 
-import java.util.Map;
-import java.util.Optional;
-
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
 import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
 import org.openecomp.sdc.be.model.jsontitan.operations.ExternalReferencesOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
+import java.util.Map;
+import java.util.Optional;
+
 /**
  * Created by yavivi on 12/02/2018.
  */
 @Component
 public class IdMapper {
 
-    private static final Logger log = LoggerFactory.getLogger(ExternalReferencesOperation.class);
+    private static final Logger log = Logger.getLogger(ExternalReferencesOperation.class.getName());
 
     public String mapComponentNameToUniqueId(String componentInstanceName, GraphVertex serviceVertex) {
         return map(componentInstanceName, serviceVertex, true);
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/InterfaceUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/InterfaceUtils.java
index 49f1694..a350d7e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/InterfaceUtils.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/InterfaceUtils.java
@@ -15,15 +15,6 @@
  */
 package org.openecomp.sdc.be.model.jsontitan.utils;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Formatter;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition;
@@ -35,6 +26,9 @@
 import org.openecomp.sdc.be.model.Operation;
 import org.openecomp.sdc.be.model.Resource;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 public class InterfaceUtils {
 
     public static final String INTERFACE_TOSCA_RESOURCE_NAME = "org.openecomp.interfaces.node.lifecycle.%s";
@@ -66,8 +60,9 @@
 
     public static String createInterfaceToscaResourceName(String resourceName) {
         StringBuilder sb = new StringBuilder();
-        Formatter formatter = new Formatter(sb);
-        return formatter.format(INTERFACE_TOSCA_RESOURCE_NAME, resourceName).toString();
+        try (Formatter formatter = new Formatter(sb)){
+            return formatter.format(INTERFACE_TOSCA_RESOURCE_NAME, resourceName).toString();
+        }
     }
 
     public static Map<String, Operation> getInterfaceOperationsFromInterfaces(
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
index bbe607b..041d3f0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
@@ -12,7 +12,7 @@
  * 
  * 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.
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.T
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * ============LICENSE_END=========================================================
@@ -20,66 +20,21 @@
 
 package org.openecomp.sdc.be.model.jsontitan.utils;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
-import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
-import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListCapabiltyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.*;
+import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
+import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
-import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-import org.openecomp.sdc.be.model.CapabilityDefinition;
-import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceInput;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.DistributionStatusEnum;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.GroupInstance;
-import org.openecomp.sdc.be.model.InputDefinition;
-import org.openecomp.sdc.be.model.InterfaceDefinition;
-import org.openecomp.sdc.be.model.PolicyDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.RelationshipImpl;
-import org.openecomp.sdc.be.model.RelationshipInfo;
-import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
-import org.openecomp.sdc.be.model.RequirementDefinition;
-import org.openecomp.sdc.be.model.Resource;
-import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
@@ -89,72 +44,76 @@
 import org.openecomp.sdc.be.resources.data.ProductMetadataData;
 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
 import org.openecomp.sdc.be.resources.data.ServiceMetadataData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 public class ModelConverter {
-	public static final String CAP_PROP_DELIM = "#";
-	private static Logger log = LoggerFactory.getLogger(ModelConverter.class.getName());
+    public static final String CAP_PROP_DELIM = "#";
+    private static final Logger log = Logger.getLogger(ModelConverter.class);
 
-	@SuppressWarnings("unchecked")
-	public static <T extends ToscaElement> T convertToToscaElement(Component component) {
-		if (isAtomicComponent(component)) {
-			return (T) convertToNodeType(component);
-		}
-		return (T) convertToTopologyTemplate(component);
-	}
+    @SuppressWarnings("unchecked")
+    public static <T extends ToscaElement> T convertToToscaElement(Component component) {
+        if (isAtomicComponent(component)) {
+            return (T) convertToNodeType(component);
+        }
+        return (T) convertToTopologyTemplate(component);
+    }
 
-	@SuppressWarnings("unchecked")
-	public static <T extends Component> T convertFromToscaElement(ToscaElement toscaElement) {
-		switch (toscaElement.getComponentType()) {
-		case RESOURCE:
-			return (T) convertToResource(toscaElement);
-		case SERVICE:
-		case PRODUCT:
-			return (T) convertToService(toscaElement);
-		default:
-			return null;
-		}
-	}
-	
-	public static boolean isAtomicComponent(Component component) {
-		ComponentTypeEnum componentType = component.getComponentType();
-		if (!componentType.equals(ComponentTypeEnum.RESOURCE)) {
-			return false;
-		}
-		Resource resource = (Resource) component;
-		ResourceTypeEnum resType = resource.getResourceType();
-		return isAtomicComponent(resType);
-	}
-	
-	public static boolean isAtomicComponent(ResourceTypeEnum resourceType) {
-		if (resourceType == null) {
-			return false;
-		}
-		return resourceType.isAtomicType();
-	}
+    @SuppressWarnings("unchecked")
+    public static <T extends Component> T convertFromToscaElement(ToscaElement toscaElement) {
+        switch (toscaElement.getComponentType()) {
+        case RESOURCE:
+            return (T) convertToResource(toscaElement);
+        case SERVICE:
+        case PRODUCT:
+            return (T) convertToService(toscaElement);
+        default:
+            return null;
+        }
+    }
 
-	// **********************************************************
-	public static VertexTypeEnum getVertexType(Component component) {
-		VertexTypeEnum vertexType;
-		if (isAtomicComponent(component)) {
-			vertexType = VertexTypeEnum.NODE_TYPE;
-		} else {
-			vertexType = VertexTypeEnum.TOPOLOGY_TEMPLATE;
-		}
-		return vertexType;
-	}
+    public static boolean isAtomicComponent(Component component) {
+        ComponentTypeEnum componentType = component.getComponentType();
+        if (!componentType.equals(ComponentTypeEnum.RESOURCE)) {
+            return false;
+        }
+        Resource resource = (Resource) component;
+        ResourceTypeEnum resType = resource.getResourceType();
+        return isAtomicComponent(resType);
+    }
 
-	public static VertexTypeEnum getVertexType(String resourceTypeName) {
-		VertexTypeEnum vertexType = null;
-		ResourceTypeEnum resourceType = ResourceTypeEnum.getTypeByName(resourceTypeName);
-		if (isAtomicComponent(resourceType)) {
-			vertexType = VertexTypeEnum.NODE_TYPE;
-		} else {
-			vertexType = VertexTypeEnum.TOPOLOGY_TEMPLATE;
-		}
-		return vertexType;
-	}
+    public static boolean isAtomicComponent(ResourceTypeEnum resourceType) {
+        if (resourceType == null) {
+            return false;
+        }
+        return resourceType.isAtomicType();
+    }
+
+    // **********************************************************
+    public static VertexTypeEnum getVertexType(Component component) {
+        VertexTypeEnum vertexType;
+        if (isAtomicComponent(component)) {
+            vertexType = VertexTypeEnum.NODE_TYPE;
+        } else {
+            vertexType = VertexTypeEnum.TOPOLOGY_TEMPLATE;
+        }
+        return vertexType;
+    }
+
+    public static VertexTypeEnum getVertexType(String resourceTypeName) {
+        VertexTypeEnum vertexType = null;
+        ResourceTypeEnum resourceType = ResourceTypeEnum.getTypeByName(resourceTypeName);
+        if (isAtomicComponent(resourceType)) {
+            vertexType = VertexTypeEnum.NODE_TYPE;
+        } else {
+            vertexType = VertexTypeEnum.TOPOLOGY_TEMPLATE;
+        }
+        return vertexType;
+    }
 
 	
 
@@ -162,57 +121,58 @@
 		Service service = new Service();
 		convertComponentFields(service, toscaElement);
 
-		convertServiceSpecificFields(toscaElement, service);
+        convertServiceSpecificFields(toscaElement, service);
 
-		TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
+        TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
 
-		convertComponentInstances(topologyTemplate, service);
+        convertComponentInstances(topologyTemplate, service);
 
-		convertInputs(topologyTemplate, service);
-		
-		convertPolicies(topologyTemplate, service);
+        convertInputs(topologyTemplate, service);
 
-		convertGroups(topologyTemplate, service);
+        convertGroups(topologyTemplate, service);
 
-		convertPolicies(topologyTemplate, service);
+		setCapabilitiesToComponentAndGroups(topologyTemplate, service);
 
-		convertGroups(topologyTemplate, service);
+        convertPolicies(topologyTemplate, service);
 
-		convertPolicies(topologyTemplate, service);
+        convertRelations(topologyTemplate, service);
 
-		convertRelations(topologyTemplate, service);
+        convertArtifacts(topologyTemplate, service);
 
-		convertArtifacts(topologyTemplate, service);
+        convertServiceApiArtifacts(topologyTemplate, service);
 
-		convertServiceApiArtifacts(topologyTemplate, service);
+        convertServicePaths(topologyTemplate, service);
 
-		convertServicePaths(topologyTemplate, service);
-
-		return service;
-	}
+        return service;
+    }
 
 	private static void convertServiceSpecificFields(ToscaElement toscaElement, Service service) {
 		service.setProjectCode((String) toscaElement.getMetadataValue(JsonPresentationFields.PROJECT_CODE));
-		service.setDistributionStatus(DistributionStatusEnum.findState((String) toscaElement.getMetadataValue(JsonPresentationFields.DISTRIBUTION_STATUS)));
-		service.setEcompGeneratedNaming((Boolean) toscaElement.getMetadataValueOrDefault(JsonPresentationFields.ECOMP_GENERATED_NAMING, true));
-		service.setNamingPolicy((String) toscaElement.getMetadataValueOrDefault(JsonPresentationFields.NAMING_POLICY, StringUtils.EMPTY));
-		service.setEnvironmentContext((String) toscaElement.getMetadataValue(JsonPresentationFields.ENVIRONMENT_CONTEXT));
+		service.setDistributionStatus(DistributionStatusEnum
+				.findState((String) toscaElement.getMetadataValue(JsonPresentationFields.DISTRIBUTION_STATUS)));
+		service.setEcompGeneratedNaming(
+				(Boolean) toscaElement.getMetadataValueOrDefault(JsonPresentationFields.ECOMP_GENERATED_NAMING, true));
+		service.setNamingPolicy((String) toscaElement.getMetadataValueOrDefault(JsonPresentationFields.NAMING_POLICY,
+				StringUtils.EMPTY));
+		service.setEnvironmentContext(
+				(String) toscaElement.getMetadataValue(JsonPresentationFields.ENVIRONMENT_CONTEXT));
+		service.setInstantiationType((String) toscaElement.getMetadataValueOrDefault(JsonPresentationFields.INSTANTIATION_TYPE, StringUtils.EMPTY));
 	}
 
-	private static Resource convertToResource(ToscaElement toscaElement) {
-		Resource resource = new Resource();
-		convertComponentFields(resource, toscaElement);
+    private static Resource convertToResource(ToscaElement toscaElement) {
+        Resource resource = new Resource();
+        convertComponentFields(resource, toscaElement);
 
-		resource.setResourceType(toscaElement.getResourceType());
-		if (toscaElement.getToscaType() == ToscaElementTypeEnum.NodeType) {
-			NodeType nodeType = (NodeType) toscaElement;
-			resource.setDerivedFrom(nodeType.getDerivedFrom());
-			resource.setDerivedList(nodeType.getDerivedList());
-			resource.setAbstract((Boolean) nodeType.getMetadataValue(JsonPresentationFields.IS_ABSTRACT));
-			convertAttributes(nodeType, resource);
-			convertCapabilities(nodeType, resource);
-			convertRequirements(nodeType, resource);
-			convertInterfaces(nodeType, resource);
+        resource.setResourceType(toscaElement.getResourceType());
+        if (toscaElement.getToscaType() == ToscaElementTypeEnum.NODE_TYPE) {
+            NodeType nodeType = (NodeType) toscaElement;
+            resource.setDerivedFrom(nodeType.getDerivedFrom());
+            resource.setDerivedList(nodeType.getDerivedList());
+            resource.setAbstract((Boolean) nodeType.getMetadataValue(JsonPresentationFields.IS_ABSTRACT));
+            convertAttributes(nodeType, resource);
+            convertCapabilities(nodeType, resource);
+            convertRequirements(nodeType, resource);
+            convertInterfaces(nodeType, resource);
 
 		} else {
 			TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
@@ -220,1145 +180,1233 @@
 				resource.setCsarUUID((String) topologyTemplate.getMetadataValue(JsonPresentationFields.CSAR_UUID));
 				resource.setCsarVersion((String) topologyTemplate.getMetadataValue(JsonPresentationFields.CSAR_VERSION));
 				resource.setImportedToscaChecksum((String) topologyTemplate.getMetadataValue(JsonPresentationFields.IMPORTED_TOSCA_CHECKSUM));
-				convertInterfaces(topologyTemplate, resource);
 
-			}
-			convertComponentInstances(topologyTemplate, resource);
-			convertRelations(topologyTemplate, resource);
-			convertInputs(topologyTemplate, resource);
-			convertGroups(topologyTemplate, resource);
-			convertPolicies(topologyTemplate, resource);
-		}
-		convertArtifacts(toscaElement, resource);
-		convertAdditionalInformation(toscaElement, resource);
+            }
+            convertComponentInstances(topologyTemplate, resource);
+            convertRelations(topologyTemplate, resource);
+            convertInputs(topologyTemplate, resource);
+            convertGroups(topologyTemplate, resource);
+			setCapabilitiesToComponentAndGroups(topologyTemplate, resource);
+            convertPolicies(topologyTemplate, resource);
+        }
+        convertArtifacts(toscaElement, resource);
+        convertAdditionalInformation(toscaElement, resource);
 
-		return resource;
-	}
+        return resource;
+    }
 
-	private static void convertInterfaces(TopologyTemplate toscaElement, Resource resource) {
-		Map<String, InterfaceDataDefinition> interfaces = toscaElement.getInterfaces();
-		Map<String, InterfaceDefinition> copy;
-		if (interfaces != null) {
-			copy = interfaces.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new InterfaceDefinition(e.getValue())));
-		} else {
-			copy = new HashMap<>();
-		}
-		resource.setInterfaces(copy);
-	}
+    private static void convertAttributes(NodeType nodeType, Resource resource) {
+        Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
+        if (attributes != null) {
+            List<PropertyDefinition> attrs = attributes.values().stream().map(dataDef -> ModelConverter.fromDataDefinition(resource.getUniqueId(), dataDef)).collect(Collectors.toList());
+            resource.setAttributes(attrs);
+        }
+    }
 
-	private static void convertAttributes(NodeType nodeType, Resource resource) {
-		Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
-		if (attributes != null) {
-			List<PropertyDefinition> attrs = attributes.values().stream().map(dataDef -> ModelConverter.fromDataDefinition(resource.getUniqueId(), dataDef)).collect(Collectors.toList());
-			resource.setAttributes(attrs);
-		}
-	}
+    private static PropertyDefinition fromDataDefinition(String resourceId, PropertyDataDefinition dataDefinition) {
+        PropertyDefinition attributeDefinition = new PropertyDefinition(dataDefinition);
+        attributeDefinition.setParentUniqueId(resourceId);
+        return attributeDefinition;
+    }
 
-	private static PropertyDefinition fromDataDefinition(String resourceId, PropertyDataDefinition dataDefinition) {
-		PropertyDefinition attributeDefinition = new PropertyDefinition(dataDefinition);
-		attributeDefinition.setParentUniqueId(resourceId);
-		return attributeDefinition;
-	}
+    private static void convertInterfaces(NodeType nodeType, Resource resource) {
+        Map<String, InterfaceDataDefinition> interfaceArtifacts = nodeType.getInterfaceArtifacts();
+        if (interfaceArtifacts != null) {
+            Map<String, InterfaceDefinition> interfaces = interfaceArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, en -> new InterfaceDefinition(en.getValue())));
+            resource.setInterfaces(interfaces);
+        }
+    }
 
-	private static void convertInterfaces(NodeType nodeType, Resource resource) {
-		Map<String, InterfaceDataDefinition> interfaceArtifacts = nodeType.getInterfaceArtifacts();
-		if (interfaceArtifacts != null) {
-			Map<String, InterfaceDefinition> interfaces = interfaceArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, en -> new InterfaceDefinition(en.getValue())));
-			resource.setInterfaces(interfaces);
-		}
-	}
+    /**
+     * Converts component instances of topology template to component instances of resource
+     *
+     * @param topologyTemplate
+     * @param component
+     */
+    public static void convertComponentInstances(TopologyTemplate topologyTemplate, Component component) {
 
-	/**
-	 * Converts component instances of topology template to component instances of resource
-	 * 
-	 * @param topologyTemplate
-	 * @param component
-	 */
-	public static void convertComponentInstances(TopologyTemplate topologyTemplate, Component component) {
+        if (MapUtils.isNotEmpty(topologyTemplate.getComponentInstances())) {
 
-		if (MapUtils.isNotEmpty(topologyTemplate.getComponentInstances())) {
+            setComponentInstancesAttributesToComponent(topologyTemplate, component);
 
-			setComponentInstancesAttributesToComponent(topologyTemplate, component);
+            setComponentInstancesPropertiesToComponent(topologyTemplate, component);
 
-			setComponentInstancesPropertiesToComponent(topologyTemplate, component);
+            setComponentInstancesInputsToComponent(topologyTemplate, component);
 
-			setComponentInstancesInputsToComponent(topologyTemplate, component);
+            setComponentInstancesToComponent(topologyTemplate, component);
 
-			setComponentInstancesToComponent(topologyTemplate, component);
+            setComponentInstancesCapabilitiesToComponentAndCI(topologyTemplate, component);
 
-			setComponentInstancesCapabilitiesToComponentAndCI(topologyTemplate, component);
+            setComponentInstancesRequirementsToComponent(topologyTemplate, component);
 
-			setComponentInstancesRequirementsToComponent(topologyTemplate, component);
+            setComponentInstancesArtifactsToComponent(topologyTemplate, component);
 
-			setComponentInstancesArtifactsToComponent(topologyTemplate, component);
+        }
+    }
 
-		}
-	}
+    private static void setComponentInstancesArtifactsToComponent(TopologyTemplate topologyTemplate, Component component) {
+        Map<String, MapArtifactDataDefinition> instDeploymentArtifacts = topologyTemplate.getInstDeploymentArtifacts();
+        Map<String, MapArtifactDataDefinition> instanceArtifacts = topologyTemplate.getInstanceArtifacts();
 
-	private static void setComponentInstancesArtifactsToComponent(TopologyTemplate topologyTemplate, Component component) {
-		Map<String, MapArtifactDataDefinition> instDeploymentArtifacts = topologyTemplate.getInstDeploymentArtifacts();
-		Map<String, MapArtifactDataDefinition> instanceArtifacts = topologyTemplate.getInstanceArtifacts();
+        List<ComponentInstance> instances = component.getComponentInstances();
+        if (instDeploymentArtifacts != null && instances != null) {
+            instDeploymentArtifacts.entrySet().forEach(e -> {
+                Optional<ComponentInstance> ci = instances.stream().filter(i -> i.getUniqueId().equals(e.getKey())).findFirst();
+                if (ci.isPresent()) {
+                    Map<String, ArtifactDataDefinition> mapToscaDataDefinition = e.getValue().getMapToscaDataDefinition();
+                    Map<String, ArtifactDefinition> deplArt = mapToscaDataDefinition.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, en -> new ArtifactDefinition(en.getValue())));
 
-		List<ComponentInstance> instances = component.getComponentInstances();
-		if (instDeploymentArtifacts != null && instances != null) {
-			instDeploymentArtifacts.entrySet().forEach(e -> {
-				Optional<ComponentInstance> ci = instances.stream().filter(i -> i.getUniqueId().equals(e.getKey())).findFirst();
-				if (ci.isPresent()) {
-					Map<String, ArtifactDataDefinition> mapToscaDataDefinition = e.getValue().getMapToscaDataDefinition();
-					Map<String, ArtifactDefinition> deplArt = mapToscaDataDefinition.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, en -> new ArtifactDefinition(en.getValue())));
+                    ci.get().setDeploymentArtifacts(deplArt);
+                }
+            });
+        }
+        if (instanceArtifacts != null && instances != null) {
+            instanceArtifacts.entrySet().forEach(e -> {
+                Optional<ComponentInstance> ci = instances.stream().filter(i -> i.getUniqueId().equals(e.getKey())).findFirst();
+                if (ci.isPresent()) {
+                    Map<String, ArtifactDataDefinition> mapToscaDataDefinition = e.getValue().getMapToscaDataDefinition();
+                    Map<String, ArtifactDefinition> deplArt = mapToscaDataDefinition.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, en -> new ArtifactDefinition(en.getValue())));
 
-					ci.get().setDeploymentArtifacts(deplArt);
-				}
-			});
-		}
-		if (instanceArtifacts != null && instances != null) {
-			instanceArtifacts.entrySet().forEach(e -> {
-				Optional<ComponentInstance> ci = instances.stream().filter(i -> i.getUniqueId().equals(e.getKey())).findFirst();
-				if (ci.isPresent()) {
-					Map<String, ArtifactDataDefinition> mapToscaDataDefinition = e.getValue().getMapToscaDataDefinition();
-					Map<String, ArtifactDefinition> deplArt = mapToscaDataDefinition.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, en -> new ArtifactDefinition(en.getValue())));
+                    ci.get().setArtifacts(deplArt);
+                }
+            });
+        }
 
-					ci.get().setArtifacts(deplArt);
-				}
-			});
-		}
+    }
 
-	}
+    public static void convertComponentInstances(Component component, TopologyTemplate topologyTemplate) {
 
-	public static void convertComponentInstances(Component component, TopologyTemplate topologyTemplate) {
+        if (!CollectionUtils.isEmpty(component.getComponentInstances())) {
 
-		if (!CollectionUtils.isEmpty(component.getComponentInstances())) {
+            setComponentInstancesAttributesToTopologyTemplate(component, topologyTemplate);
 
-			setComponentInstancesAttributesToTopologyTemplate(component, topologyTemplate);
+            setComponentInstancesPropertiesToTopologyTemplate(component, topologyTemplate);
 
-			setComponentInstancesPropertiesToTopologyTemplate(component, topologyTemplate);
+            setComponentInstancesInputsToTopologyTemplate(component, topologyTemplate);
 
-			setComponentInstancesInputsToTopologyTemplate(component, topologyTemplate);
+            setComponentInstancesToTopologyTemplate(component, topologyTemplate);
 
-			setComponentInstancesToTopologyTemplate(component, topologyTemplate);
+            setComponentInstancesArtifactsToTopologyTemplate(component, topologyTemplate);
+        }
+    }
 
-			setComponentInstancesArtifactsToTopologyTemplate(component, topologyTemplate);
-		}
-	}
+    public static void convertRelations(TopologyTemplate topologyTemplate, Component component) {
+        Map<String, RelationshipInstDataDefinition> relations = topologyTemplate.getRelations();
+        List<RequirementCapabilityRelDef> componentRelations;
+        if (relations != null && !relations.isEmpty()) {
+            componentRelations = relations.values().stream().map(ModelConverter::convertRelation).collect(Collectors.toList());
 
-	public static void convertRelations(TopologyTemplate topologyTemplate, Component component) {
-		Map<String, RelationshipInstDataDefinition> relations = topologyTemplate.getRelations();
-		List<RequirementCapabilityRelDef> componentRelations;
-		if (relations != null && !relations.isEmpty()) {
-			componentRelations = relations.values().stream().map(ModelConverter::convertRelation).collect(Collectors.toList());
+        } else {
+            componentRelations = new ArrayList<>();
+        }
+        component.setComponentInstancesRelations(componentRelations);
 
-		} else {
-			componentRelations = new ArrayList<>();
-		}
-		component.setComponentInstancesRelations(componentRelations);
+    }
 
-	}
+    public static RequirementCapabilityRelDef convertRelation(RelationshipInstDataDefinition relation) {
+        RequirementCapabilityRelDef requirementCapabilityRelDef = new RequirementCapabilityRelDef();
+        requirementCapabilityRelDef.setFromNode(relation.getFromId());
+        requirementCapabilityRelDef.setToNode(relation.getToId());
+        requirementCapabilityRelDef.setOriginUI(BooleanUtils.isTrue(relation.isOriginUI()));
 
-	public static RequirementCapabilityRelDef convertRelation(RelationshipInstDataDefinition relation) {
-		RequirementCapabilityRelDef requirementCapabilityRelDef = new RequirementCapabilityRelDef();
-		requirementCapabilityRelDef.setFromNode(relation.getFromId());
-		requirementCapabilityRelDef.setToNode(relation.getToId());
-		RelationshipInfo relationshipPair = new RelationshipInfo();
-		relationshipPair.setId(relation.getUniqueId());
-		relationshipPair.setCapabilityOwnerId(relation.getCapabilityOwnerId());
-		relationshipPair.setCapabilityUid(relation.getCapabilityId());
-		relationshipPair.setCapability(relation.getCapability());
-		relationshipPair.setRequirementOwnerId(relation.getRequirementOwnerId());
-		relationshipPair.setRequirementUid(relation.getRequirementId());
-		relationshipPair.setRequirement(relation.getRequirement());
-		RelationshipImpl relationship = new RelationshipImpl();
-		relationship.setType(relation.getType());
-		relationshipPair.setRelationships(relationship);
-		CapabilityRequirementRelationship rel = new CapabilityRequirementRelationship();
-		rel.setRelation(relationshipPair);
-		List<CapabilityRequirementRelationship> relationships = new ArrayList<>();
-		relationships.add(rel);
-		requirementCapabilityRelDef.setRelationships(relationships);
-		return requirementCapabilityRelDef;
-	}
+        CapabilityRequirementRelationship rel = new CapabilityRequirementRelationship();
+        RelationshipInfo relationshipPair = getRelationshipInfo(relation);
+        rel.setRelation(relationshipPair);
+        requirementCapabilityRelDef.setRelationships(Arrays.asList(rel));
 
-	public static List<RelationshipInstDataDefinition> convertRelationToToscaRelation(RequirementCapabilityRelDef relation) {
+        return requirementCapabilityRelDef;
+    }
 
-		List<RelationshipInstDataDefinition> relationsList = new ArrayList<>();
+    /**
+     * @param relation
+     * @return
+     */
+    private static RelationshipInfo getRelationshipInfo(RelationshipInstDataDefinition relation) {
+        RelationshipInfo relationshipPair = new RelationshipInfo();
 
-		List<CapabilityRequirementRelationship> relationship = relation.getRelationships();
-		relationship.forEach(p -> {
-			RelationshipInstDataDefinition requirementCapabilityRelDef = new RelationshipInstDataDefinition();
-			requirementCapabilityRelDef.setFromId(relation.getFromNode());
-			requirementCapabilityRelDef.setToId(relation.getToNode());
-			requirementCapabilityRelDef.setUniqueId(p.getRelation().getId());
-			requirementCapabilityRelDef.setCapabilityOwnerId(p.getRelation().getCapabilityOwnerId());
-			requirementCapabilityRelDef.setCapabilityId(p.getRelation().getCapabilityUid());
-			requirementCapabilityRelDef.setRequirementOwnerId(p.getRelation().getRequirementOwnerId());
-			requirementCapabilityRelDef.setRequirementId(p.getRelation().getRequirementUid());
-			requirementCapabilityRelDef.setRequirement(p.getRelation().getRequirement());
-			requirementCapabilityRelDef.setType(p.getRelation().getRelationship().getType());
-			requirementCapabilityRelDef.setCapability(p.getRelation().getCapability());
+        relationshipPair.setId(relation.getUniqueId());
 
-			relationsList.add(requirementCapabilityRelDef);
-		});
+        relationshipPair.setCapabilityOwnerId(relation.getCapabilityOwnerId());
+        relationshipPair.setCapabilityUid(relation.getCapabilityId());
+        relationshipPair.setCapability(relation.getCapability());
 
-		return relationsList;
-	}
+        relationshipPair.setRequirementOwnerId(relation.getRequirementOwnerId());
+        relationshipPair.setRequirementUid(relation.getRequirementId());
+        relationshipPair.setRequirement(relation.getRequirement());
 
-	private static void convertCapabilities(Component component, TopologyTemplate topologyTemplate) {
+        RelationshipImpl relationship = new RelationshipImpl();
+        relationship.setType(relation.getType());
+        relationshipPair.setRelationships(relationship);
 
-		if (component.getCapabilities() != null && component.getComponentInstances() != null) {
-			topologyTemplate.setCalculatedCapabilities(new HashMap<>());
-			topologyTemplate.setCalculatedCapabilitiesProperties(new HashMap<>());
-			for (ComponentInstance instance : component.getComponentInstances()) {
-				Map<String, List<CapabilityDefinition>> instCapabilities = instance.getCapabilities();
-				if (MapUtils.isNotEmpty(instCapabilities)) {
-					if (topologyTemplate.getCalculatedCapabilities() == null) {
-						topologyTemplate.setCalculatedCapabilities(new HashMap<>());
-					}
-					topologyTemplate.getCalculatedCapabilities().put(instance.getUniqueId(), convertToMapListCapabiltyDataDefinition(instCapabilities));
-					if (topologyTemplate.getCalculatedCapabilitiesProperties() == null) {
-						topologyTemplate.setCalculatedCapabilitiesProperties(new HashMap<>());
-					}
-					topologyTemplate.getCalculatedCapabilitiesProperties().put(instance.getUniqueId(), convertToMapOfMapCapabiltyProperties(instCapabilities, instance.getUniqueId()));
-				}
-			}
-		}
-	}
+        return relationshipPair;
+    }
 
-	public static MapCapabiltyProperty convertToMapOfMapCapabiltyProperties(Map<String, List<CapabilityDefinition>> instCapabilities, String instanceId) {
-		return convertToMapOfMapCapabiltyProperties(instCapabilities, instanceId, false);
-	}
 
-	public static MapCapabiltyProperty convertToMapOfMapCapabiltyProperties(Map<String, List<CapabilityDefinition>> instCapabilities, String instanceId, boolean fromCsar) {
+    public static List<RelationshipInstDataDefinition> convertRelationToToscaRelation(RequirementCapabilityRelDef relation) {
 
-		Map<String, MapPropertiesDataDefinition> toscaCapPropMap = new HashMap<>();
+        List<RelationshipInstDataDefinition> relationsList = new ArrayList<>();
 
-		instCapabilities.forEach(new BiConsumer<String, List<CapabilityDefinition>>() {
-			@Override
-			public void accept(String s, List<CapabilityDefinition> caps) {
+        List<CapabilityRequirementRelationship> relationship = relation.getRelationships();
+        relationship.forEach(p -> {
+            RelationshipInstDataDefinition requirementCapabilityRelDef = new RelationshipInstDataDefinition();
+            requirementCapabilityRelDef.setFromId(relation.getFromNode());
+            requirementCapabilityRelDef.setToId(relation.getToNode());
+            requirementCapabilityRelDef.setUniqueId(p.getRelation().getId());
+            requirementCapabilityRelDef.setCapabilityOwnerId(p.getRelation().getCapabilityOwnerId());
+            requirementCapabilityRelDef.setCapabilityId(p.getRelation().getCapabilityUid());
+            requirementCapabilityRelDef.setRequirementOwnerId(p.getRelation().getRequirementOwnerId());
+            requirementCapabilityRelDef.setRequirementId(p.getRelation().getRequirementUid());
+            requirementCapabilityRelDef.setRequirement(p.getRelation().getRequirement());
+            requirementCapabilityRelDef.setType(p.getRelation().getRelationship().getType());
+            requirementCapabilityRelDef.setCapability(p.getRelation().getCapability());
 
-				if (caps != null && !caps.isEmpty()) {
+            relationsList.add(requirementCapabilityRelDef);
+        });
 
-					MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
+        return relationsList;
+    }
 
-					for (CapabilityDefinition cap : caps) {
-						List<ComponentInstanceProperty> capPrps = cap.getProperties();
-						if (capPrps != null) {
-
-							for (ComponentInstanceProperty cip : capPrps) {
-								dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
-							}
-							// format key of capability properties :
-							// VF instance in service : instanceId#ownerId#type#capName
-							// VFC instance ion VF : instanceId#ownerId#type#capName -> instanceId=ownerId
-
-							StringBuffer sb = new StringBuffer(instanceId);
-							sb.append(CAP_PROP_DELIM);
-							if (fromCsar) {
-								sb.append(instanceId);
-							} else {
-								sb.append(cap.getOwnerId());
-							}
-							sb.append(CAP_PROP_DELIM).append(s).append(CAP_PROP_DELIM).append(cap.getName());
-							toscaCapPropMap.put(sb.toString(), new MapPropertiesDataDefinition(dataToCreate));
-						}
-					}
-
-				}
-
-			}
-		});
-		return new MapCapabiltyProperty(toscaCapPropMap);
-	}
-
-	private static MapListCapabiltyDataDefinition convertToMapListCapabiltyDataDefinition(Map<String, List<CapabilityDefinition>> instCapabilities) {
-
-		Map<String, ListCapabilityDataDefinition> mapToscaDataDefinition = new HashMap<>();
-		for (Entry<String, List<CapabilityDefinition>> instCapability : instCapabilities.entrySet()) {
-			mapToscaDataDefinition.put(instCapability.getKey(), new ListCapabilityDataDefinition(instCapability.getValue().stream().map(iCap -> new CapabilityDataDefinition(iCap)).collect(Collectors.toList())));
-		}
-
-		return new MapListCapabiltyDataDefinition(mapToscaDataDefinition);
-	}
-
-	private static void convertRequirements(Component component, TopologyTemplate topologyTemplate) {
-
-		if (component.getRequirements() != null && component.getComponentInstances() != null) {
-			topologyTemplate.setCalculatedRequirements(new HashMap<>());
-			for (ComponentInstance instance : component.getComponentInstances()) {
-				Map<String, List<RequirementDefinition>> instRequirements = instance.getRequirements();
-				if (MapUtils.isNotEmpty(instRequirements)) {
-					if (topologyTemplate.getCalculatedRequirements() == null) {
-						topologyTemplate.setCalculatedRequirements(new HashMap<>());
-					}
-					topologyTemplate.getCalculatedRequirements().put(instance.getUniqueId(), convertToMapListRequirementDataDefinition(instRequirements));
-				}
-			}
-		}
-	}
-
-	private static MapListRequirementDataDefinition convertToMapListRequirementDataDefinition(Map<String, List<RequirementDefinition>> instRequirements) {
-
-		Map<String, ListRequirementDataDefinition> mapToscaDataDefinition = new HashMap<>();
-		for (Entry<String, List<RequirementDefinition>> instRequirement : instRequirements.entrySet()) {
-			mapToscaDataDefinition.put(instRequirement.getKey(), new ListRequirementDataDefinition(instRequirement.getValue().stream().map(iCap -> new RequirementDataDefinition(iCap)).collect(Collectors.toList())));
-		}
-
-		return new MapListRequirementDataDefinition(mapToscaDataDefinition);
-	}
-
-	@SuppressWarnings("unchecked")
-	private static void convertComponentFields(Component component, ToscaElement toscaElement) {
-		component.setName(toscaElement.getName());
-		component.setAllVersions(toscaElement.getAllVersions());
-		component.setCategories(toscaElement.getCategories());
-		component.setComponentType(toscaElement.getComponentType());
-		component.setCreationDate(toscaElement.getCreationDate());
-		component.setCreatorUserId(toscaElement.getCreatorUserId());
-		component.setCreatorFullName(toscaElement.getCreatorFullName());
-		component.setLastUpdateDate(toscaElement.getLastUpdateDate());
-		component.setLastUpdaterFullName(toscaElement.getLastUpdaterFullName());
-		component.setLastUpdaterUserId(toscaElement.getLastUpdaterUserId());
-		component.setNormalizedName(toscaElement.getNormalizedName());
-
-		component.setLifecycleState(toscaElement.getLifecycleState());
-		component.setVersion(toscaElement.getVersion());
-		component.setHighestVersion(toscaElement.isHighestVersion());
-		component.setUniqueId(toscaElement.getUniqueId());
-		component.setSystemName((String) toscaElement.getMetadataValue(JsonPresentationFields.SYSTEM_NAME));
-		component.setDerivedFromGenericType(toscaElement.getDerivedFromGenericType());
-		component.setDerivedFromGenericVersion(toscaElement.getDerivedFromGenericVersion());
-
-		if (component.getComponentType() == ComponentTypeEnum.RESOURCE) {
-			Resource resource = (Resource) component;
-			resource.setAbstract((Boolean) toscaElement.getMetadataValue(JsonPresentationFields.IS_ABSTRACT));
-			resource.setToscaResourceName((String) toscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
-			resource.setVendorName((String) toscaElement.getMetadataValue(JsonPresentationFields.VENDOR_NAME));
-			resource.setVendorRelease((String) toscaElement.getMetadataValue(JsonPresentationFields.VENDOR_RELEASE));
-			// field isn't mandatory , but shouldn't be null(should be an empty string instead)
-			if (((String) toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER)) != null){
-				resource.setResourceVendorModelNumber((String) toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER));
-			} else {
-				resource.setResourceVendorModelNumber("");
-			}
-		} else if (component.getComponentType() == ComponentTypeEnum.SERVICE) {
-			Service service = (Service) component;
-			if (((String) toscaElement.getMetadataValue(JsonPresentationFields.SERVICE_TYPE)) != null){
-				service.setServiceType((String) toscaElement.getMetadataValue(JsonPresentationFields.SERVICE_TYPE));
-			} else {
-				service.setServiceType("");
-			}
-			if (((String) toscaElement.getMetadataValue(JsonPresentationFields.SERVICE_ROLE)) != null){
-				service.setServiceRole((String) toscaElement.getMetadataValue(JsonPresentationFields.SERVICE_ROLE));
-			} else {
-				service.setServiceRole("");
-			}
-		}
-		component.setConformanceLevel((String) toscaElement.getMetadataValue(JsonPresentationFields.CONFORMANCE_LEVEL));
-		component.setIcon((String) toscaElement.getMetadataValue(JsonPresentationFields.ICON));
-		component.setDescription((String) toscaElement.getMetadataValue(JsonPresentationFields.DESCRIPTION));
-		component.setTags((List<String>) toscaElement.getMetadataValue(JsonPresentationFields.TAGS));
-		component.setInvariantUUID((String) toscaElement.getMetadataValue(JsonPresentationFields.INVARIANT_UUID));
-		component.setContactId((String) toscaElement.getMetadataValue(JsonPresentationFields.CONTACT_ID));
-		component.setUUID((String) toscaElement.getMetadataValue(JsonPresentationFields.UUID));
-		component.setIsDeleted((Boolean) toscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED));
-
-		Map<String, PropertyDataDefinition> properties = toscaElement.getProperties();
-		if (properties != null && !properties.isEmpty()) {
-			List<PropertyDefinition> propertiesMap = properties.values().stream().map(x -> new PropertyDefinition(x)).collect(Collectors.toList());
-			((Resource) component).setProperties(propertiesMap);
-		}
-
-		component.setToscaType(toscaElement.getToscaType().getValue());
-	}
-
-	private static NodeType convertToNodeType(Component component) {
-		Resource resource = (Resource) component;
-		NodeType nodeType = new NodeType();
-		nodeType.setDerivedFrom(resource.getDerivedFrom());
-		nodeType.setDerivedList(resource.getDerivedList());
-		nodeType.setResourceType(resource.getResourceType());
-		// nodeType.setCapabiltiesProperties(capabiltiesProperties);
-		convertCommonToscaData(component, nodeType);
-		convertAdditionalInformation(component, nodeType);
-		convertArtifacts(resource, nodeType);
-		convertCapabilities(resource, nodeType);
-		convertRequirements(resource, nodeType);
-		convertAttributes(resource, nodeType);
-		convertProperties(resource, nodeType);
-		convertInterfaces(resource, nodeType);
-		return nodeType;
-	}
-
-	private static void convertProperties(Resource resource, NodeType nodeType) {
-		List<PropertyDefinition> properties = resource.getProperties();
-		if (properties != null && !properties.isEmpty()) {
-			Map<String, PropertyDataDefinition> propertiesMap = properties.stream().collect(Collectors.toMap(x -> x.getName(), x -> new PropertyDataDefinition(x)));
-			nodeType.setProperties(propertiesMap);
-		}
-	}
-
-	private static void convertInterfaces(Resource resource, NodeType nodeType) {
-		Map<String, InterfaceDefinition> interfaces = resource.getInterfaces();
-		if (interfaces != null) {
-			Map<String, InterfaceDataDefinition> interfaceArtifacts = interfaces.entrySet().stream().collect(Collectors.toMap(x -> x.getKey(), x -> new InterfaceDataDefinition(x.getValue())));
-			nodeType.setInterfaceArtifacts(interfaceArtifacts);
-		}
-	}
-
-	private static void convertAdditionalInformation(Component component, ToscaElement toscaElement) {
-		List<AdditionalInformationDefinition> additionalInformation = component.getAdditionalInformation();
-		if (additionalInformation != null) {
-			Map<String, AdditionalInfoParameterDataDefinition> addInfo = additionalInformation.stream().collect(Collectors.toMap(x -> x.getUniqueId(), x -> new AdditionalInfoParameterDataDefinition(x)));
-			toscaElement.setAdditionalInformation(addInfo);
-		}
-	}
-
-	private static void convertAdditionalInformation(ToscaElement toscaElement, Component resource) {
-		Map<String, AdditionalInfoParameterDataDefinition> additionalInformation = toscaElement.getAdditionalInformation();
-		if (additionalInformation != null) {
-			List<AdditionalInformationDefinition> addInfo = additionalInformation.values().stream().map(e -> {
-				return new AdditionalInformationDefinition(e);
-			}).collect(Collectors.toList());
-			resource.setAdditionalInformation(addInfo);
-		}
-	}
-
-	private static void convertArtifacts(ToscaElement toscaElement, Component component) {
-		Map<String, ArtifactDataDefinition> artifacts = toscaElement.getArtifacts();
-		Map<String, ArtifactDefinition> copy;
-		if (artifacts != null) {
-			copy = artifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDefinition(e.getValue())));
-
-		} else {
-			copy = new HashMap<>();
-		}
-		component.setArtifacts(copy);
-
-		Map<String, ArtifactDataDefinition> toscaArtifacts = toscaElement.getToscaArtifacts();
-		if (toscaArtifacts != null) {
-			copy = toscaArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDefinition(e.getValue())));
-
-		} else {
-			copy = new HashMap<>();
-		}
-		component.setToscaArtifacts(copy);
-
-		Map<String, ArtifactDataDefinition> deploymentArtifacts = toscaElement.getDeploymentArtifacts();
-		if (deploymentArtifacts != null) {
-			copy = deploymentArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDefinition(e.getValue())));
-
-		} else {
-			copy = new HashMap<>();
-		}
-		component.setDeploymentArtifacts(copy);
-	}
-
-	private static void convertServiceApiArtifacts(TopologyTemplate topologyTemplate, Service service) {
-		Map<String, ArtifactDataDefinition> serviceApiArtifacts = topologyTemplate.getServiceApiArtifacts();
-		Map<String, ArtifactDefinition> copy;
-		if (serviceApiArtifacts != null) {
-			copy = serviceApiArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDefinition(e.getValue())));
-
-		} else {
-			copy = new HashMap<>();
-		}
-		service.setServiceApiArtifacts(copy);
-	}
-	private static void convertServicePaths(TopologyTemplate topologyTemplate, Service service) {
-		Map<String, ForwardingPathDataDefinition> servicePaths = topologyTemplate.getForwardingPaths();
-		Map<String, ForwardingPathDataDefinition> copy;
-		if (servicePaths != null) {
-			copy = servicePaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ForwardingPathDataDefinition(e.getValue())));
-
-		} else {
-			copy = new HashMap<>();
-		}
-		service.setForwardingPaths(copy);
-	}
-
-	private static void convertArtifacts(Component component, ToscaElement toscaElement) {
-		Map<String, ArtifactDefinition> artifacts = component.getArtifacts();
-		if (artifacts != null) {
-			Map<String, ArtifactDataDefinition> copy = artifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
-			toscaElement.setArtifacts(copy);
-		}
+    private static void convertCapabilities(Component component, TopologyTemplate topologyTemplate) {
+        if(componentInstancesCapabilitiesExist(component) || groupsCapabilitiesExist(component)){
+            topologyTemplate.setCalculatedCapabilities(new HashMap<>());
+            topologyTemplate.setCalculatedCapabilitiesProperties(new HashMap<>());
+        }
+        convertComponentInstancesCapabilities(component, topologyTemplate);
+        convertGroupsCapabilities(component, topologyTemplate);
+    }
 
-		Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
-		if (toscaArtifacts != null) {
-			Map<String, ArtifactDataDefinition> copy = toscaArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
-			toscaElement.setToscaArtifacts(copy);
-		}
+    private static void convertGroupsCapabilities(Component component, TopologyTemplate topologyTemplate) {
+        if(groupsCapabilitiesExist(component)){
+            component.getGroups()
+                    .stream()
+                    .filter(g -> MapUtils.isNotEmpty(g.getCapabilities()))
+                    .forEach(g -> addCapabilities(topologyTemplate, g.getCapabilities(), g.getUniqueId()));
+        }
+    }
 
-		Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
-		if (deploymentArtifacts != null) {
-			Map<String, ArtifactDataDefinition> copy = deploymentArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
-			toscaElement.setDeploymentArtifacts(copy);
-		}
-	}
+    private static void convertComponentInstancesCapabilities(Component component, TopologyTemplate topologyTemplate) {
+        if (componentInstancesCapabilitiesExist(component)) {
+            component.getComponentInstances()
+                    .stream()
+                    .filter(i -> MapUtils.isNotEmpty(i.getCapabilities()))
+                    .forEach(i -> addCapabilities(topologyTemplate, i.getCapabilities(), i.getUniqueId()));
+        }
+    }
 
-	private static void convertServiceApiArtifacts(Service service, TopologyTemplate topologyTemplate) {
-		Map<String, ArtifactDefinition> serviceApiArtifacts = service.getServiceApiArtifacts();
-		if (serviceApiArtifacts != null) {
-			Map<String, ArtifactDataDefinition> copy = serviceApiArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
-			topologyTemplate.setServiceApiArtifacts(copy);
-		}
-	}
+    private static void addCapabilities(TopologyTemplate topologyTemplate, Map<String, List<CapabilityDefinition>> capabilities, String ownerId) {
+        if (MapUtils.isNotEmpty(capabilities)) {
+            if (topologyTemplate.getCalculatedCapabilities() == null) {
+                topologyTemplate.setCalculatedCapabilities(new HashMap<>());
+            }
+            topologyTemplate.getCalculatedCapabilities().put(ownerId, convertToMapListCapabiltyDataDefinition(capabilities));
+            if (topologyTemplate.getCalculatedCapabilitiesProperties() == null) {
+                topologyTemplate.setCalculatedCapabilitiesProperties(new HashMap<>());
+            }
+            topologyTemplate.getCalculatedCapabilitiesProperties().put(ownerId, convertToMapOfMapCapabiltyProperties(capabilities, ownerId));
+        }
+    }
 
-	private static void convertCapabilities(Component component, NodeType toscaElement) {
-		Map<String, List<CapabilityDefinition>> capabilities = component.getCapabilities();
+    private static boolean componentInstancesCapabilitiesExist(Component component) {
+        return component.getCapabilities() != null && component.getComponentInstances() != null
+                && component.getComponentInstances()
+                .stream()
+                .filter(ci->MapUtils.isNotEmpty(ci.getCapabilities()))
+                .findFirst()
+                .isPresent();
+    }
+    private static boolean groupsCapabilitiesExist(Component component) {
+        return component.getCapabilities() != null && component.getGroups() != null
+                && component.getGroups()
+                .stream()
+                .filter(g->MapUtils.isNotEmpty(g.getCapabilities()))
+                .findFirst()
+                .isPresent();
+    }
+    public static MapCapabilityProperty convertToMapOfMapCapabiltyProperties(Map<String, List<CapabilityDefinition>> instCapabilities, String ownerId) {
+        return convertToMapOfMapCapabiltyProperties(instCapabilities, ownerId, false);
+    }
 
-		Map<String, ListCapabilityDataDefinition> toscaCapMap = new HashMap<>();
-		Map<String, MapPropertiesDataDefinition> toscaCapPropMap = new HashMap<>();
+	public static MapCapabilityProperty convertToMapOfMapCapabiltyProperties(Map<String, List<CapabilityDefinition>> capabilities, String ownerId, boolean fromCsar) {
 
-		if (capabilities != null && !capabilities.isEmpty()) {
-			capabilities.forEach(new BiConsumer<String, List<CapabilityDefinition>>() {
-				@Override
-				public void accept(String s, List<CapabilityDefinition> caps) {
+        Map<String, MapPropertiesDataDefinition> toscaCapPropMap = new HashMap<>();
+		if(MapUtils.isNotEmpty(capabilities))
+			capabilities.forEach((s, caps)-> {
 
 					if (caps != null && !caps.isEmpty()) {
-						List<CapabilityDataDefinition> capList = caps.stream().map(o -> {
-							return new CapabilityDataDefinition(o);
-						}).collect(Collectors.toList());
 
-						ListCapabilityDataDefinition listCapabilityDataDefinition = new ListCapabilityDataDefinition(capList);
-						toscaCapMap.put(s, listCapabilityDataDefinition);
+						MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
 
 						for (CapabilityDefinition cap : caps) {
 							List<ComponentInstanceProperty> capPrps = cap.getProperties();
-							if (capPrps != null && !capPrps.isEmpty()) {
+							if (capPrps != null) {
 
-								MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
 								for (ComponentInstanceProperty cip : capPrps) {
 									dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
 								}
+								// format key of capability properties :
+								// VF instance in service : instanceId#ownerId#type#capName
+								// VFC instance ion VF : instanceId#ownerId#type#capName -> instanceId=ownerId
 
-								toscaCapPropMap.put(s + CAP_PROP_DELIM + cap.getName(), dataToCreate);
+								StringBuilder sb = new StringBuilder(ownerId);
+								sb.append(CAP_PROP_DELIM);
+								if (fromCsar) {
+									sb.append(ownerId);
+								} else {
+									sb.append(cap.getOwnerId());
+								}
+								sb.append(CAP_PROP_DELIM).append(s).append(CAP_PROP_DELIM).append(cap.getName());
+								toscaCapPropMap.put(sb.toString(), new MapPropertiesDataDefinition(dataToCreate));
 							}
 						}
-
-					}
-
-				}
-			});
-
-			toscaElement.setCapabilties(toscaCapMap);
-			toscaElement.setCapabiltiesProperties(toscaCapPropMap);
-		}
-	}
-
-	private static void convertAttributes(Resource component, NodeType nodeType) {
-		List<PropertyDefinition> attributes = component.getAttributes();
-		if (attributes != null) {
-			Map<String, PropertyDataDefinition> attrsByName = attributes.stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, Function.identity()));
-			nodeType.setAttributes(attrsByName);
-		}
-	}
-
-	private static void convertRequirements(Resource component, NodeType nodeType) {
-		Map<String, List<RequirementDefinition>> requirements = component.getRequirements();
-
-		Map<String, ListRequirementDataDefinition> toscaReqMap = new HashMap<>();
-
-		if (requirements != null && !requirements.isEmpty()) {
-			requirements.forEach(new BiConsumer<String, List<RequirementDefinition>>() {
-				@Override
-				public void accept(String s, List<RequirementDefinition> reqs) {
-
-					if (reqs != null && !reqs.isEmpty()) {
-						List<RequirementDataDefinition> reqList = reqs.stream().map(o -> {
-							return new RequirementDataDefinition(o);
-						}).collect(Collectors.toList());
-
-						ListRequirementDataDefinition listRequirementDataDefinition = new ListRequirementDataDefinition(reqList);
-						toscaReqMap.put(s, listRequirementDataDefinition);
 					}
 				}
-			});
-			nodeType.setRequirements(toscaReqMap);
-		}
-	}
+			);
+        return new MapCapabilityProperty(toscaCapPropMap);
+    }
 
-	private static void convertCapabilities(NodeType toscaElement, Component component) {
-		Map<String, ListCapabilityDataDefinition> toscaCapabilities = toscaElement.getCapabilties();
-		Map<String, MapPropertiesDataDefinition> toscaCapPropMap = toscaElement.getCapabiltiesProperties();
+	private static MapListCapabilityDataDefinition convertToMapListCapabiltyDataDefinition(Map<String, List<CapabilityDefinition>> instCapabilities) {
 
-		Map<String, List<CapabilityDefinition>> compCap = new HashMap<>();
-		if (toscaCapabilities == null || toscaCapabilities.isEmpty())
-			return;
-		toscaCapabilities.forEach(new BiConsumer<String, ListCapabilityDataDefinition>() {
-			@Override
-			public void accept(String s, ListCapabilityDataDefinition cap) {
+        Map<String, ListCapabilityDataDefinition> mapToscaDataDefinition = new HashMap<>();
+        for (Entry<String, List<CapabilityDefinition>> instCapability : instCapabilities.entrySet()) {
+			mapToscaDataDefinition.put(instCapability.getKey(), new ListCapabilityDataDefinition(instCapability.getValue().stream().map(CapabilityDataDefinition::new).collect(Collectors.toList())));
+        }
 
-				if (cap != null) {
-					List<CapabilityDataDefinition> capDataList = cap.getListToscaDataDefinition();
+        return new MapListCapabilityDataDefinition(mapToscaDataDefinition);
+    }
 
-					if (capDataList != null && !capDataList.isEmpty()) {
-						List<CapabilityDefinition> capList = capDataList.stream().map(o -> {
+    private static void convertRequirements(Component component, TopologyTemplate topologyTemplate) {
 
-							return new CapabilityDefinition(o);
-						}).collect(Collectors.toList());
-						compCap.put(s, capList);
-					}
-				}
+        if (component.getRequirements() != null && component.getComponentInstances() != null) {
+            topologyTemplate.setCalculatedRequirements(new HashMap<>());
+            for (ComponentInstance instance : component.getComponentInstances()) {
+                Map<String, List<RequirementDefinition>> instRequirements = instance.getRequirements();
+                if (MapUtils.isNotEmpty(instRequirements)) {
+                    if (topologyTemplate.getCalculatedRequirements() == null) {
+                        topologyTemplate.setCalculatedRequirements(new HashMap<>());
+                    }
+                    topologyTemplate.getCalculatedRequirements().put(instance.getUniqueId(), convertToMapListRequirementDataDefinition(instRequirements));
+                }
+            }
+        }
+    }
 
-			}
-		});
-		if (toscaCapPropMap != null && !toscaCapPropMap.isEmpty()) {
-			toscaCapPropMap.forEach(new BiConsumer<String, MapPropertiesDataDefinition>() {
-				@Override
-				public void accept(String s, MapPropertiesDataDefinition capProp) {
-					String[] result = s.split(CAP_PROP_DELIM);
-					if (capProp != null) {
-						Map<String, PropertyDataDefinition> capMap = capProp.getMapToscaDataDefinition();
+    private static MapListRequirementDataDefinition convertToMapListRequirementDataDefinition(Map<String, List<RequirementDefinition>> instRequirements) {
 
-						if (capMap != null && !capMap.isEmpty()) {
-							// List<PropertyDataDefinition> list = map.values().stream().collect(Collectors.toList());
-							List<ComponentInstanceProperty> capPropsList = capMap.values().stream().map(o -> {
+        Map<String, ListRequirementDataDefinition> mapToscaDataDefinition = new HashMap<>();
+        for (Entry<String, List<RequirementDefinition>> instRequirement : instRequirements.entrySet()) {
+			mapToscaDataDefinition.put(instRequirement.getKey(), new ListRequirementDataDefinition(instRequirement.getValue().stream().map(RequirementDataDefinition::new).collect(Collectors.toList())));
+        }
 
-								return new ComponentInstanceProperty(o);
-							}).collect(Collectors.toList());
+        return new MapListRequirementDataDefinition(mapToscaDataDefinition);
+    }
 
-							List<CapabilityDefinition> cap = compCap.get(result[0]);
-							Optional<CapabilityDefinition> op = cap.stream().filter(c -> c.getName().equals(result[1])).findFirst();
-							if (op.isPresent()) {
-								op.get().setProperties(capPropsList);
-							}
-						}
+    @SuppressWarnings("unchecked")
+    private static void convertComponentFields(Component component, ToscaElement toscaElement) {
+        component.setName(toscaElement.getName());
+        component.setAllVersions(toscaElement.getAllVersions());
+        component.setCategories(toscaElement.getCategories());
+        component.setComponentType(toscaElement.getComponentType());
+        component.setCreationDate(toscaElement.getCreationDate());
+        component.setCreatorUserId(toscaElement.getCreatorUserId());
+        component.setCreatorFullName(toscaElement.getCreatorFullName());
+        component.setLastUpdateDate(toscaElement.getLastUpdateDate());
+        component.setLastUpdaterFullName(toscaElement.getLastUpdaterFullName());
+        component.setLastUpdaterUserId(toscaElement.getLastUpdaterUserId());
+        component.setNormalizedName(toscaElement.getNormalizedName());
 
-					}
+        component.setLifecycleState(toscaElement.getLifecycleState());
+        component.setVersion(toscaElement.getVersion());
+        component.setHighestVersion(toscaElement.isHighestVersion());
+        component.setUniqueId(toscaElement.getUniqueId());
+        component.setSystemName((String) toscaElement.getMetadataValue(JsonPresentationFields.SYSTEM_NAME));
+        component.setDerivedFromGenericType(toscaElement.getDerivedFromGenericType());
+        component.setDerivedFromGenericVersion(toscaElement.getDerivedFromGenericVersion());
 
-				}
-			});
-		}
+        //archive
+        component.setArchived(toscaElement.isArchived() == null ? false : toscaElement.isArchived());
 
-		component.setCapabilities(compCap);
 
-	}
+        //component.setArchiveTime(toscaElement.getArchiveTime() == null ? 0L : toscaElement.getArchiveTime());
+        component.setArchiveTime(toscaElement.getArchiveTime());
+        component.setVspArchived(toscaElement.isVspArchived() == null ? false : toscaElement.isVspArchived());
 
-	private static void convertGroups(TopologyTemplate toscaElement, Component component) {
-		Map<String, GroupDataDefinition> toscaGroups = toscaElement.getGroups();
-		List<GroupDefinition> groupDefinitions = null;
-		if (MapUtils.isNotEmpty(toscaGroups)) {
-			groupDefinitions = toscaGroups.values().stream().map(g -> new GroupDefinition(g)).collect(Collectors.toList());
-		}
-		component.setGroups(groupDefinitions);
-	}
-	
-	private static void convertPolicies(TopologyTemplate toscaElement, Component component) {
-		Map<String, PolicyDataDefinition> policies = toscaElement.getPolicies();
-		Map<String, PolicyDefinition> policyDefinitions = null;
-		if (MapUtils.isNotEmpty(policies)) {
-			policyDefinitions = policies.values().stream().map(p -> new PolicyDefinition(p)).collect(Collectors.toMap(p->p.getUniqueId(), p->p));
-		}
-		component.setPolicies(policyDefinitions);
-	}
+        if (component.getComponentType() == ComponentTypeEnum.RESOURCE) {
+            Resource resource = (Resource) component;
+            resource.setAbstract((Boolean) toscaElement.getMetadataValue(JsonPresentationFields.IS_ABSTRACT));
+            resource.setToscaResourceName((String) toscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
+            resource.setVendorName((String) toscaElement.getMetadataValue(JsonPresentationFields.VENDOR_NAME));
+            resource.setVendorRelease((String) toscaElement.getMetadataValue(JsonPresentationFields.VENDOR_RELEASE));
+            // field isn't mandatory , but shouldn't be null(should be an empty string instead)
+            if (((String) toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER)) != null){
+                resource.setResourceVendorModelNumber((String) toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER));
+            } else {
+                resource.setResourceVendorModelNumber("");
+            }
+        } else if (component.getComponentType() == ComponentTypeEnum.SERVICE) {
+            Service service = (Service) component;
+            if (((String) toscaElement.getMetadataValue(JsonPresentationFields.SERVICE_TYPE)) != null){
+                service.setServiceType((String) toscaElement.getMetadataValue(JsonPresentationFields.SERVICE_TYPE));
+            } else {
+                service.setServiceType("");
+            }
+            if (((String) toscaElement.getMetadataValue(JsonPresentationFields.SERVICE_ROLE)) != null){
+                service.setServiceRole((String) toscaElement.getMetadataValue(JsonPresentationFields.SERVICE_ROLE));
+            } else {
+                service.setServiceRole("");
+            }
+        }
+        component.setConformanceLevel((String) toscaElement.getMetadataValue(JsonPresentationFields.CONFORMANCE_LEVEL));
+        component.setIcon((String) toscaElement.getMetadataValue(JsonPresentationFields.ICON));
+        component.setDescription((String) toscaElement.getMetadataValue(JsonPresentationFields.DESCRIPTION));
+        component.setTags((List<String>) toscaElement.getMetadataValue(JsonPresentationFields.TAGS));
+        component.setInvariantUUID((String) toscaElement.getMetadataValue(JsonPresentationFields.INVARIANT_UUID));
+        component.setContactId((String) toscaElement.getMetadataValue(JsonPresentationFields.CONTACT_ID));
+        component.setUUID((String) toscaElement.getMetadataValue(JsonPresentationFields.UUID));
+        component.setIsDeleted((Boolean) toscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED));
 
-	private static void convertGroups(Component component, TopologyTemplate toscaElement) {
-		List<GroupDefinition> groupDefinitions = component.getGroups();
-		Map<String, GroupDataDefinition> groups = new HashMap<>();
 
-		if (groupDefinitions != null && groups.isEmpty()) {
-			groups = groupDefinitions.stream().collect(Collectors.toMap(pr -> pr.getName(), pr -> new GroupDataDefinition(pr)));
-		}
-		toscaElement.setGroups(groups);
-	}
-	
-	private static void convertPolicies(Component component, TopologyTemplate toscaElement) {
-		Map<String, PolicyDefinition> policyDefinitions = component.getPolicies();
-		Map<String, PolicyDataDefinition> policies = new HashMap<>();
-		if (MapUtils.isNotEmpty(policyDefinitions)) {
-			policies = policyDefinitions.values().stream().collect((Collectors.toMap(p -> p.getUniqueId(), p -> new PolicyDataDefinition(p))));
-		}
-		toscaElement.setPolicies(policies);
-	}
+        Map<String, PropertyDataDefinition> properties = toscaElement.getProperties();
+        if (properties != null && !properties.isEmpty()) {
+			List<PropertyDefinition> propertiesMap = properties.values().stream().map(PropertyDefinition::new).collect(Collectors.toList());
+            ((Resource) component).setProperties(propertiesMap);
+        }
 
-	private static void convertRequirements(NodeType toscaElement, Component component) {
-		Map<String, ListRequirementDataDefinition> toscaRequirements = toscaElement.getRequirements();
+        component.setToscaType(toscaElement.getToscaType().getValue());
+    }
 
-		Map<String, List<RequirementDefinition>> compReqs = new HashMap<>();
-		if (toscaRequirements == null || toscaRequirements.isEmpty())
-			return;
-		toscaRequirements.forEach(new BiConsumer<String, ListRequirementDataDefinition>() {
-			@Override
-			public void accept(String s, ListRequirementDataDefinition req) {
+    private static NodeType convertToNodeType(Component component) {
+        Resource resource = (Resource) component;
+        NodeType nodeType = new NodeType();
+        nodeType.setDerivedFrom(resource.getDerivedFrom());
+        nodeType.setDerivedList(resource.getDerivedList());
+        nodeType.setResourceType(resource.getResourceType());
+        convertCommonToscaData(component, nodeType);
+        convertAdditionalInformation(component, nodeType);
+        convertArtifacts(resource, nodeType);
+        convertCapabilities(resource, nodeType);
+        convertRequirements(resource, nodeType);
+        convertAttributes(resource, nodeType);
+        convertProperties(resource, nodeType);
+        convertInterfaces(resource, nodeType);
+        return nodeType;
+    }
 
-				if (req != null) {
-					List<RequirementDataDefinition> reqDataList = req.getListToscaDataDefinition();
+    private static void convertProperties(Resource resource, NodeType nodeType) {
+        List<PropertyDefinition> properties = resource.getProperties();
+        if (properties != null && !properties.isEmpty()) {
+			Map<String, PropertyDataDefinition> propertiesMap = properties.stream().collect(Collectors.toMap(PropertyDefinition::getName, PropertyDataDefinition::new));
+            nodeType.setProperties(propertiesMap);
+        }
+    }
 
-					if (reqDataList != null && !reqDataList.isEmpty()) {
-						List<RequirementDefinition> reqList = reqDataList.stream().map(o -> {
+    private static void convertInterfaces(Resource resource, NodeType nodeType) {
+        Map<String, InterfaceDefinition> interfaces = resource.getInterfaces();
+        if (interfaces != null) {
+			Map<String, InterfaceDataDefinition> interfaceArtifacts = interfaces.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, x -> new InterfaceDataDefinition(x.getValue())));
+            nodeType.setInterfaceArtifacts(interfaceArtifacts);
+        }
+    }
 
-							return new RequirementDefinition(o);
-						}).collect(Collectors.toList());
-						compReqs.put(s, reqList);
-					}
-				}
-			}
-		});
-		component.setRequirements(compReqs);
-	}
+    private static void convertAdditionalInformation(Component component, ToscaElement toscaElement) {
+        List<AdditionalInformationDefinition> additionalInformation = component.getAdditionalInformation();
+        if (additionalInformation != null) {
+			Map<String, AdditionalInfoParameterDataDefinition> addInfo = additionalInformation.stream().collect(Collectors.toMap(AdditionalInformationDefinition::getUniqueId, AdditionalInfoParameterDataDefinition::new));
+            toscaElement.setAdditionalInformation(addInfo);
+        }
+    }
 
-	private static TopologyTemplate convertToTopologyTemplate(Component component) {
-		TopologyTemplate topologyTemplate;
-		ComponentTypeEnum componentType = component.getComponentType();
-		topologyTemplate = new TopologyTemplate();
+    private static void convertAdditionalInformation(ToscaElement toscaElement, Component resource) {
+        Map<String, AdditionalInfoParameterDataDefinition> additionalInformation = toscaElement.getAdditionalInformation();
+        if (additionalInformation != null) {
+			List<AdditionalInformationDefinition> addInfo = additionalInformation.values().stream().map(AdditionalInformationDefinition::new).collect(Collectors.toList());
+            resource.setAdditionalInformation(addInfo);
+        }
+    }
 
-		if (componentType == ComponentTypeEnum.RESOURCE) {
-			Resource resource = (Resource) component;
-			topologyTemplate.setResourceType(resource.getResourceType());
-			topologyTemplate.setMetadataValue(JsonPresentationFields.CSAR_UUID, resource.getCsarUUID());
-			topologyTemplate.setMetadataValue(JsonPresentationFields.CSAR_VERSION, resource.getCsarVersion());
-			topologyTemplate.setMetadataValue(JsonPresentationFields.IMPORTED_TOSCA_CHECKSUM, resource.getImportedToscaChecksum());
-			convertInterfaces(resource, topologyTemplate);
-		}
-		if (componentType == ComponentTypeEnum.SERVICE) {
-			convertServiceSpecificEntities((Service) component, topologyTemplate);
-		}
-		convertCommonToscaData(component, topologyTemplate);
-		convertArtifacts(component, topologyTemplate);
+    private static void convertArtifacts(ToscaElement toscaElement, Component component) {
+        Map<String, ArtifactDataDefinition> artifacts = toscaElement.getArtifacts();
+        Map<String, ArtifactDefinition> copy;
+        if (artifacts != null) {
+            copy = artifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDefinition(e.getValue())));
 
-		convertAdditionalInformation(component, topologyTemplate);
-		convertComponentInstances(component, topologyTemplate);
+        } else {
+            copy = new HashMap<>();
+        }
+        component.setArtifacts(copy);
 
-		convertInputs(component, topologyTemplate);
-		convertCapabilities(component, topologyTemplate);
-		convertGroups(component, topologyTemplate);
-		convertPolicies(component, topologyTemplate);
-		convertRequirements(component, topologyTemplate);
-		convertRelationsToComposition(component, topologyTemplate);
+        Map<String, ArtifactDataDefinition> toscaArtifacts = toscaElement.getToscaArtifacts();
+        if (toscaArtifacts != null) {
+            copy = toscaArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDefinition(e.getValue())));
 
-		return topologyTemplate;
-	}
+        } else {
+            copy = new HashMap<>();
+        }
+        component.setToscaArtifacts(copy);
 
-	private static void convertInterfaces(Resource resource, TopologyTemplate topologyTemplate) {
-		Map<String, InterfaceDefinition> interfaces = resource.getInterfaces();
-		if (interfaces != null && !interfaces.isEmpty()) {
-			Map<String, InterfaceDataDefinition> copy = interfaces.entrySet().stream()
-					.collect(Collectors.toMap(Map.Entry::getKey, e -> new InterfaceDataDefinition(e.getValue())));
-			topologyTemplate.setInterfaces(copy);
-		}
-	}
+        Map<String, ArtifactDataDefinition> deploymentArtifacts = toscaElement.getDeploymentArtifacts();
+        if (deploymentArtifacts != null) {
+            copy = deploymentArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDefinition(e.getValue())));
 
-	private static void convertServiceSpecificEntities(Service service, TopologyTemplate topologyTemplate) {
-		convertServiceMetaData(service, topologyTemplate);
-		convertServiceApiArtifacts(service, topologyTemplate);
-		convertServicePaths(service,topologyTemplate);
-	}
+        } else {
+            copy = new HashMap<>();
+        }
+        component.setDeploymentArtifacts(copy);
+    }
 
-	private static void convertServicePaths(Service service, TopologyTemplate topologyTemplate) {
-		Map<String, ForwardingPathDataDefinition> servicePaths = service.getForwardingPaths();
-		if (servicePaths != null && !servicePaths.isEmpty()) {
-			Map<String, ForwardingPathDataDefinition> copy = servicePaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ForwardingPathDataDefinition(e.getValue())));
-			topologyTemplate.setForwardingPaths(copy);
-		}
-	}
+    private static void convertServiceApiArtifacts(TopologyTemplate topologyTemplate, Service service) {
+        Map<String, ArtifactDataDefinition> serviceApiArtifacts = topologyTemplate.getServiceApiArtifacts();
+        Map<String, ArtifactDefinition> copy;
+        if (serviceApiArtifacts != null) {
+            copy = serviceApiArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDefinition(e.getValue())));
+
+        } else {
+            copy = new HashMap<>();
+        }
+        service.setServiceApiArtifacts(copy);
+    }
+    private static void convertServicePaths(TopologyTemplate topologyTemplate, Service service) {
+        Map<String, ForwardingPathDataDefinition> servicePaths = topologyTemplate.getForwardingPaths();
+        Map<String, ForwardingPathDataDefinition> copy;
+        if (servicePaths != null) {
+            copy = servicePaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ForwardingPathDataDefinition(e.getValue())));
+
+        } else {
+            copy = new HashMap<>();
+        }
+        service.setForwardingPaths(copy);
+    }
+
+    private static void convertArtifacts(Component component, ToscaElement toscaElement) {
+        Map<String, ArtifactDefinition> artifacts = component.getArtifacts();
+        if (artifacts != null) {
+            Map<String, ArtifactDataDefinition> copy = artifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
+            toscaElement.setArtifacts(copy);
+        }
+
+        Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
+        if (toscaArtifacts != null) {
+            Map<String, ArtifactDataDefinition> copy = toscaArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
+            toscaElement.setToscaArtifacts(copy);
+        }
+
+        Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
+        if (deploymentArtifacts != null) {
+            Map<String, ArtifactDataDefinition> copy = deploymentArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
+            toscaElement.setDeploymentArtifacts(copy);
+        }
+    }
+
+    private static void convertServiceApiArtifacts(Service service, TopologyTemplate topologyTemplate) {
+        Map<String, ArtifactDefinition> serviceApiArtifacts = service.getServiceApiArtifacts();
+        if (serviceApiArtifacts != null) {
+            Map<String, ArtifactDataDefinition> copy = serviceApiArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
+            topologyTemplate.setServiceApiArtifacts(copy);
+        }
+    }
+
+    private static void convertCapabilities(Component component, NodeType toscaElement) {
+        Map<String, List<CapabilityDefinition>> capabilities = component.getCapabilities();
+
+        Map<String, ListCapabilityDataDefinition> toscaCapMap = new HashMap<>();
+        Map<String, MapPropertiesDataDefinition> toscaCapPropMap = new HashMap<>();
+
+        if (capabilities != null && !capabilities.isEmpty()) {
+			capabilities.forEach((s, caps) -> {
+
+                    if (caps != null && !caps.isEmpty()) {
+						List<CapabilityDataDefinition> capList = caps.stream().map(CapabilityDataDefinition::new).collect(Collectors.toList());
+
+                        ListCapabilityDataDefinition listCapabilityDataDefinition = new ListCapabilityDataDefinition(capList);
+                        toscaCapMap.put(s, listCapabilityDataDefinition);
+
+                        for (CapabilityDefinition cap : caps) {
+                            List<ComponentInstanceProperty> capPrps = cap.getProperties();
+                            if (capPrps != null && !capPrps.isEmpty()) {
+
+                                MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
+                                for (ComponentInstanceProperty cip : capPrps) {
+                                    dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
+                                }
+
+                                toscaCapPropMap.put(s + CAP_PROP_DELIM + cap.getName(), dataToCreate);
+                            }
+                        }
+                    }
+                }
+			);
+
+            toscaElement.setCapabilties(toscaCapMap);
+            toscaElement.setCapabiltiesProperties(toscaCapPropMap);
+        }
+    }
+
+    private static void convertAttributes(Resource component, NodeType nodeType) {
+        List<PropertyDefinition> attributes = component.getAttributes();
+        if (attributes != null) {
+            Map<String, PropertyDataDefinition> attrsByName = attributes.stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, Function.identity()));
+            nodeType.setAttributes(attrsByName);
+        }
+    }
+
+    private static void convertRequirements(Resource component, NodeType nodeType) {
+        Map<String, List<RequirementDefinition>> requirements = component.getRequirements();
+
+        Map<String, ListRequirementDataDefinition> toscaReqMap = new HashMap<>();
+
+        if (requirements != null && !requirements.isEmpty()) {
+			requirements.forEach((s, reqs)-> {
+
+                    if (reqs != null && !reqs.isEmpty()) {
+						List<RequirementDataDefinition> reqList = reqs.stream().map(RequirementDataDefinition::new).collect(Collectors.toList());
+
+                        ListRequirementDataDefinition listRequirementDataDefinition = new ListRequirementDataDefinition(reqList);
+                        toscaReqMap.put(s, listRequirementDataDefinition);
+                    }
+                }
+			);
+            nodeType.setRequirements(toscaReqMap);
+        }
+    }
+
+    private static void convertCapabilities(NodeType toscaElement, Component component) {
+        Map<String, ListCapabilityDataDefinition> toscaCapabilities = toscaElement.getCapabilties();
+        Map<String, MapPropertiesDataDefinition> toscaCapPropMap = toscaElement.getCapabiltiesProperties();
+
+        Map<String, List<CapabilityDefinition>> compCap = new HashMap<>();
+        if (toscaCapabilities == null || toscaCapabilities.isEmpty())
+            return;
+		toscaCapabilities.forEach((s, cap)-> {
+
+                if (cap != null) {
+                    List<CapabilityDataDefinition> capDataList = cap.getListToscaDataDefinition();
+
+                    if (capDataList != null && !capDataList.isEmpty()) {
+						List<CapabilityDefinition> capList = capDataList.stream().map(CapabilityDefinition::new).collect(Collectors.toList());
+                        compCap.put(s, capList);
+                    }
+                }
+
+            }
+		);
+        if (toscaCapPropMap != null && !toscaCapPropMap.isEmpty()) {
+			toscaCapPropMap.forEach((s, capProp)-> {
+                    String[] result = s.split(CAP_PROP_DELIM);
+                    if (capProp != null) {
+                        Map<String, PropertyDataDefinition> capMap = capProp.getMapToscaDataDefinition();
+
+                        if (capMap != null && !capMap.isEmpty()) {
+							List<ComponentInstanceProperty> capPropsList = capMap.values().stream().map(ComponentInstanceProperty::new).collect(Collectors.toList());
+
+                            List<CapabilityDefinition> cap = compCap.get(result[0]);
+                            Optional<CapabilityDefinition> op = cap.stream().filter(c -> c.getName().equals(result[1])).findFirst();
+                            if (op.isPresent()) {
+                                op.get().setProperties(capPropsList);
+                            }
+                        }
+                    }
+                }
+			);
+        }
+
+        component.setCapabilities(compCap);
+
+    }
+
+    private static void convertGroups(TopologyTemplate toscaElement, Component component) {
+        Map<String, GroupDataDefinition> toscaGroups = toscaElement.getGroups();
+        List<GroupDefinition> groupDefinitions = null;
+        if (MapUtils.isNotEmpty(toscaGroups)) {
+			groupDefinitions = toscaGroups.values().stream().map(GroupDefinition::new).collect(Collectors.toList());
+        }
+        component.setGroups(groupDefinitions);
+    }
+
+    private static void convertPolicies(TopologyTemplate toscaElement, Component component) {
+        Map<String, PolicyDataDefinition> policies = toscaElement.getPolicies();
+        Map<String, PolicyDefinition> policyDefinitions = null;
+        if (MapUtils.isNotEmpty(policies)) {
+			policyDefinitions = policies.values().stream().map(PolicyDefinition::new).collect(Collectors.toMap(PolicyDefinition::getUniqueId, Function.identity()));
+        }
+        component.setPolicies(policyDefinitions);
+    }
+
+    private static void convertGroups(Component component, TopologyTemplate toscaElement) {
+        List<GroupDefinition> groupDefinitions = component.getGroups();
+        Map<String, GroupDataDefinition> groups = new HashMap<>();
+
+        if (groupDefinitions != null && groups.isEmpty()) {
+			groups = groupDefinitions.stream().collect(Collectors.toMap(GroupDefinition::getName, GroupDefinition::new));
+        }
+        toscaElement.setGroups(groups);
+    }
+
+    private static void convertPolicies(Component component, TopologyTemplate toscaElement) {
+        Map<String, PolicyDefinition> policyDefinitions = component.getPolicies();
+        Map<String, PolicyDataDefinition> policies = new HashMap<>();
+        if (MapUtils.isNotEmpty(policyDefinitions)) {
+			policies = policyDefinitions.values().stream().collect((Collectors.toMap(PolicyDefinition::getUniqueId, PolicyDataDefinition::new)));
+        }
+        toscaElement.setPolicies(policies);
+    }
+
+    private static void convertRequirements(NodeType toscaElement, Component component) {
+        Map<String, ListRequirementDataDefinition> toscaRequirements = toscaElement.getRequirements();
+
+        Map<String, List<RequirementDefinition>> compReqs = new HashMap<>();
+        if (toscaRequirements == null || toscaRequirements.isEmpty())
+            return;
+		toscaRequirements.forEach((s, req) -> {
+
+                if (req != null) {
+                    List<RequirementDataDefinition> reqDataList = req.getListToscaDataDefinition();
+
+                    if (reqDataList != null && !reqDataList.isEmpty()) {
+						List<RequirementDefinition> reqList = reqDataList.stream().map(RequirementDefinition::new).collect(Collectors.toList());
+                        compReqs.put(s, reqList);
+                    }
+                }
+            }
+		);
+        component.setRequirements(compReqs);
+    }
+
+    private static TopologyTemplate convertToTopologyTemplate(Component component) {
+        TopologyTemplate topologyTemplate;
+        ComponentTypeEnum componentType = component.getComponentType();
+        topologyTemplate = new TopologyTemplate();
+
+        if (componentType == ComponentTypeEnum.RESOURCE) {
+            Resource resource = (Resource) component;
+            topologyTemplate.setResourceType(resource.getResourceType());
+            topologyTemplate.setMetadataValue(JsonPresentationFields.CSAR_UUID, resource.getCsarUUID());
+            topologyTemplate.setMetadataValue(JsonPresentationFields.CSAR_VERSION, resource.getCsarVersion());
+            topologyTemplate.setMetadataValue(JsonPresentationFields.IMPORTED_TOSCA_CHECKSUM, resource.getImportedToscaChecksum());
+        }
+        if (componentType == ComponentTypeEnum.SERVICE) {
+            convertServiceSpecificEntities((Service) component, topologyTemplate);
+        }
+        convertCommonToscaData(component, topologyTemplate);
+        convertArtifacts(component, topologyTemplate);
+
+        convertAdditionalInformation(component, topologyTemplate);
+        convertComponentInstances(component, topologyTemplate);
+
+        convertInputs(component, topologyTemplate);
+        convertCapabilities(component, topologyTemplate);
+        convertGroups(component, topologyTemplate);
+        convertPolicies(component, topologyTemplate);
+        convertRequirements(component, topologyTemplate);
+        convertRelationsToComposition(component, topologyTemplate);
+
+        return topologyTemplate;
+    }
+
+    private static void convertServiceSpecificEntities(Service service, TopologyTemplate topologyTemplate) {
+        convertServiceMetaData(service, topologyTemplate);
+        convertServiceApiArtifacts(service, topologyTemplate);
+        convertServicePaths(service,topologyTemplate);
+    }
+
+    private static void convertServicePaths(Service service, TopologyTemplate topologyTemplate) {
+        Map<String, ForwardingPathDataDefinition> servicePaths = service.getForwardingPaths();
+        if (servicePaths != null && !servicePaths.isEmpty()) {
+            Map<String, ForwardingPathDataDefinition> copy = servicePaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ForwardingPathDataDefinition(e.getValue())));
+            topologyTemplate.setForwardingPaths(copy);
+        }
+    }
 
 	private static void convertServiceMetaData(Service service, TopologyTemplate topologyTemplate) {
 		if (service.getDistributionStatus() != null) {
-			topologyTemplate.setMetadataValue(JsonPresentationFields.DISTRIBUTION_STATUS, service.getDistributionStatus().name());
+			topologyTemplate.setMetadataValue(JsonPresentationFields.DISTRIBUTION_STATUS,
+					service.getDistributionStatus().name());
 		}
 		topologyTemplate.setMetadataValue(JsonPresentationFields.PROJECT_CODE, service.getProjectCode());
-		topologyTemplate.setMetadataValue(JsonPresentationFields.ECOMP_GENERATED_NAMING, service.isEcompGeneratedNaming());
+		topologyTemplate.setMetadataValue(JsonPresentationFields.ECOMP_GENERATED_NAMING,
+				service.isEcompGeneratedNaming());
 		topologyTemplate.setMetadataValue(JsonPresentationFields.NAMING_POLICY, service.getNamingPolicy());
 		topologyTemplate.setMetadataValue(JsonPresentationFields.ENVIRONMENT_CONTEXT, service.getEnvironmentContext());
+		topologyTemplate.setMetadataValue(JsonPresentationFields.INSTANTIATION_TYPE, service.getInstantiationType());
 
-	}
+    }
 
-	private static void convertRelationsToComposition(Component component, TopologyTemplate topologyTemplate) {
-		List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
-		if (componentInstancesRelations != null) {
-			Map<String, CompositionDataDefinition> compositions = topologyTemplate.getCompositions();
-			if (compositions == null) {
-				compositions = new HashMap<>();
+    private static void convertRelationsToComposition(Component component, TopologyTemplate topologyTemplate) {
+        List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
+        if (componentInstancesRelations != null) {
+            Map<String, CompositionDataDefinition> compositions = topologyTemplate.getCompositions();
+            if (compositions == null) {
+                compositions = new HashMap<>();
+            }
+            CompositionDataDefinition compositionDataDefinition = compositions.get(JsonConstantKeysEnum.COMPOSITION.getValue());
+            if (compositionDataDefinition == null) {
+                compositionDataDefinition = new CompositionDataDefinition();
+                compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), compositionDataDefinition);
+            }
+
+            Map<String, RelationshipInstDataDefinition> relations = componentInstancesRelations.stream().flatMap(x -> convertRelationToToscaRelation(x).stream()).filter(i -> i.getUniqueId() != null)
+					.collect(Collectors.toMap(RelationshipInstDataDefinition::getUniqueId, Function.identity()));
+            compositionDataDefinition.setRelations(relations);
+        }
+    }
+
+    private static void convertInputs(Component component, TopologyTemplate topologyTemplate) {
+        List<InputDefinition> inputsList = component.getInputs();
+        if (inputsList != null && !inputsList.isEmpty()) {
+
+			Map<String, PropertyDataDefinition> inputsMap = inputsList.stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, Function.identity()));
+            topologyTemplate.setInputs(inputsMap);
+        }
+
+    }
+
+    private static void convertInputs(TopologyTemplate topologyTemplate, Component component) {
+        Map<String, PropertyDataDefinition> inputsMap = topologyTemplate.getInputs();
+        if (inputsMap != null && !inputsMap.isEmpty()) {
+			List<InputDefinition> inputsList = inputsMap.values()
+                    .stream()
+                    .map(InputDefinition::new)
+                    .collect(Collectors.toList());
+            component.setInputs(inputsList);
+        }
+
+    }
+
+    private static void convertCommonToscaData(Component component, ToscaElement toscaElement) {
+        toscaElement.setUUID(component.getUUID());
+        toscaElement.setUniqueId(component.getUniqueId());
+        toscaElement.setSystemName(component.getSystemName());
+        toscaElement.setLifecycleState(component.getLifecycleState());
+        toscaElement.setComponentType(component.getComponentType());
+        toscaElement.setNormalizedName(component.getNormalizedName());
+        toscaElement.setMetadataValue(JsonPresentationFields.NAME, component.getName());
+        toscaElement.setCategories(component.getCategories());
+        toscaElement.setCreatorUserId(component.getCreatorUserId());
+        toscaElement.setCreationDate(component.getCreationDate());
+        toscaElement.setCreatorFullName(component.getCreatorFullName());
+        toscaElement.setHighestVersion(component.isHighestVersion());
+        toscaElement.setLastUpdateDate(component.getLastUpdateDate());
+        toscaElement.setLastUpdaterFullName(component.getLastUpdaterFullName());
+        toscaElement.setLastUpdaterUserId(component.getLastUpdaterUserId());
+        toscaElement.setDerivedFromGenericType(component.getDerivedFromGenericType());
+        toscaElement.setDerivedFromGenericVersion(component.getDerivedFromGenericVersion());
+
+        //Archive
+        toscaElement.setArchived(component.isArchived() == null ? false : component.isArchived());
+        toscaElement.setArchiveTime(component.getArchiveTime() == null ? 0L : component.getArchiveTime());
+        toscaElement.setVspArchived(component.isVspArchived() == null ? false : component.isVspArchived());
+
+        toscaElement.setLifecycleState(component.getLifecycleState());
+        toscaElement.setMetadataValue(JsonPresentationFields.VERSION, component.getVersion());
+        if (component.getComponentType() == ComponentTypeEnum.RESOURCE) {
+            toscaElement.setMetadataValue(JsonPresentationFields.IS_ABSTRACT, ((Resource) component).isAbstract());
+            toscaElement.setMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME, ((Resource) component).getToscaResourceName());
+            toscaElement.setMetadataValue(JsonPresentationFields.VENDOR_NAME, ((Resource) component).getVendorName());
+            toscaElement.setMetadataValue(JsonPresentationFields.VENDOR_RELEASE, ((Resource) component).getVendorRelease());
+            // field isn't mandatory , but shouldn't be null(should be an empty string instead)
+            if (((Resource) component).getResourceVendorModelNumber() != null){
+                toscaElement.setMetadataValue(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER, ((Resource) component).getResourceVendorModelNumber());
+            } else {
+                toscaElement.setMetadataValue(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER, "");
+            }
+        } else if (component.getComponentType() == ComponentTypeEnum.SERVICE) {
+            // field isn't mandatory , but shouldn't be null(should be an empty string instead)
+            if (((Service) component).getServiceType() != null){
+                toscaElement.setMetadataValue(JsonPresentationFields.SERVICE_TYPE, ((Service) component).getServiceType());
+            } else {
+                toscaElement.setMetadataValue(JsonPresentationFields.SERVICE_TYPE, "");
+            }
+            if (((Service) component).getServiceRole() != null){
+                toscaElement.setMetadataValue(JsonPresentationFields.SERVICE_ROLE, ((Service) component).getServiceRole());
+            } else {
+                toscaElement.setMetadataValue(JsonPresentationFields.SERVICE_ROLE, "");
+            }
+        }
+        toscaElement.setMetadataValue(JsonPresentationFields.CONFORMANCE_LEVEL, component.getConformanceLevel());
+        toscaElement.setMetadataValue(JsonPresentationFields.IS_DELETED, component.getIsDeleted());
+        toscaElement.setMetadataValue(JsonPresentationFields.ICON, component.getIcon());
+        toscaElement.setMetadataValue(JsonPresentationFields.DESCRIPTION, component.getDescription());
+        toscaElement.setMetadataValue(JsonPresentationFields.TAGS, component.getTags());
+        toscaElement.setMetadataValue(JsonPresentationFields.INVARIANT_UUID, component.getInvariantUUID());
+        toscaElement.setMetadataValue(JsonPresentationFields.CONTACT_ID, component.getContactId());
+    }
+
+
+
+    private static void setComponentInstancesToComponent(TopologyTemplate topologyTemplate, Component component) {
+
+        List<ComponentInstance> componentInstances = new ArrayList<>();
+        ComponentInstance currComponentInstance;
+        for (Map.Entry<String, ComponentInstanceDataDefinition> entry : topologyTemplate.getComponentInstances().entrySet()) {
+            String key = entry.getKey();
+            currComponentInstance = new ComponentInstance(topologyTemplate.getComponentInstances().get(key));
+            if (topologyTemplate.getInstGroups() != null && topologyTemplate.getInstGroups().containsKey(key)) {
+                List<GroupInstance> groupInstances = topologyTemplate.getInstGroups().get(key).getMapToscaDataDefinition().entrySet().stream().map(e -> new GroupInstance(e.getValue())).collect(Collectors.toList());
+                currComponentInstance.setGroupInstances(groupInstances);
+            }
+            componentInstances.add(currComponentInstance);
+        }
+        component.setComponentInstances(componentInstances);
+    }
+
+    private static void setComponentInstancesInputsToComponent(TopologyTemplate topologyTemplate, Component component) {
+        if (topologyTemplate.getInstInputs() != null) {
+            Map<String, List<ComponentInstanceInput>> inputs = new HashMap<>();
+            for (Entry<String, MapPropertiesDataDefinition> entry : topologyTemplate.getInstInputs().entrySet()) {
+                if (entry.getValue() != null && entry.getValue().getMapToscaDataDefinition() != null) {
+                    String key = entry.getKey();
+                    List<ComponentInstanceInput> componentInstanceAttributes = entry.getValue().getMapToscaDataDefinition().entrySet().stream().map(e -> new ComponentInstanceInput(e.getValue())).collect(Collectors.toList());
+                    inputs.put(key, componentInstanceAttributes);
+                }
+            }
+            component.setComponentInstancesInputs(inputs);
+        }
+    }
+
+    private static void setComponentInstancesPropertiesToComponent(TopologyTemplate topologyTemplate, Component component) {
+        if (topologyTemplate.getInstProperties() != null) {
+            Map<String, List<ComponentInstanceProperty>> properties = new HashMap<>();
+            for (Entry<String, MapPropertiesDataDefinition> entry : topologyTemplate.getInstProperties().entrySet()) {
+                if (entry.getValue() != null && entry.getValue().getMapToscaDataDefinition() != null) {
+                    String key = entry.getKey();
+                    List<ComponentInstanceProperty> componentInstanceAttributes = entry.getValue().getMapToscaDataDefinition().entrySet().stream().map(e -> new ComponentInstanceProperty(new PropertyDefinition(e.getValue())))
+                            .collect(Collectors.toList());
+                    properties.put(key, componentInstanceAttributes);
+                }
+            }
+            component.setComponentInstancesProperties(properties);
+        }
+    }
+
+    private static void setComponentInstancesAttributesToComponent(TopologyTemplate topologyTemplate, Component component) {
+        if (topologyTemplate.getInstAttributes() != null) {
+            Map<String, List<ComponentInstanceProperty>> attributes = new HashMap<>();
+            for (Map.Entry<String, MapPropertiesDataDefinition> entry : topologyTemplate.getInstAttributes().entrySet()) {
+                if (entry.getValue() != null && entry.getValue().getMapToscaDataDefinition() != null) {
+                    String key = entry.getKey();
+                    List<ComponentInstanceProperty> componentInstanceAttributes = entry.getValue().getMapToscaDataDefinition().entrySet().stream().map(e -> new ComponentInstanceProperty(new ComponentInstanceProperty(e.getValue())))
+                            .collect(Collectors.toList());
+                    attributes.put(key, componentInstanceAttributes);
+                }
+            }
+            component.setComponentInstancesAttributes(attributes);
+        }
+    }
+
+    private static void setComponentInstancesRequirementsToComponent(TopologyTemplate topologyTemplate, Component component) {
+
+        if (topologyTemplate.getCalculatedRequirements() != null) {
+            // Requirements of component organized by capability
+            Map<String, List<RequirementDefinition>> instancesRequirements = new HashMap<>();
+
+            Map<String, ComponentInstance> instancesMap = new HashMap<>();
+            for (ComponentInstance currInstance : component.getComponentInstances()) {
+                instancesMap.put(currInstance.getUniqueId(), currInstance);
+            }
+            for (Map.Entry<String, MapListRequirementDataDefinition> entry : topologyTemplate.getCalculatedRequirements().entrySet()) {
+
+                String instanceId = entry.getKey();
+                // Requirements of instance organized by capability
+                Map<String, ListRequirementDataDefinition> capsMapList = entry.getValue().getMapToscaDataDefinition();
+
+                if(capsMapList != null) {
+                    for (Entry<String, ListRequirementDataDefinition> entryTypeList : capsMapList.entrySet()) {
+                        String capabilityType = entryTypeList.getKey();
+					List<RequirementDefinition> caps = entryTypeList.getValue().getListToscaDataDefinition().stream().map(RequirementDefinition::new).collect(Collectors.toList());
+                        if (instancesRequirements.containsKey(capabilityType)) {
+                            instancesRequirements.get(capabilityType).addAll(caps);
+                        } else {
+                            instancesRequirements.put(capabilityType, caps);
+                        }
+                        if (MapUtils.isEmpty(instancesMap.get(instanceId).getRequirements())) {
+                            instancesMap.get(instanceId).setRequirements(new HashMap<>());
+                        }
+                        instancesMap.get(instanceId).getRequirements().put(capabilityType, new ArrayList<>(caps));
+                    }
+                }
+            }
+            component.setRequirements(instancesRequirements);
+        }
+    }
+
+    private static void setComponentInstancesCapabilitiesToComponentAndCI(TopologyTemplate topologyTemplate, Component component) {
+        Map<String, MapCapabilityProperty> calculatedCapProperties = topologyTemplate.getCalculatedCapabilitiesProperties();
+
+        if (topologyTemplate.getCalculatedCapabilities() != null) {
+            // capabilities of component organized by type
+            Map<String, List<CapabilityDefinition>> instancesCapabilities = new HashMap<>();
+
+            Map<String, ComponentInstance> instancesMap = new HashMap<>();
+            for (ComponentInstance currInstance : component.getComponentInstances()) {
+                instancesMap.put(currInstance.getUniqueId(), currInstance);
+            }
+            for (Map.Entry<String, MapListCapabilityDataDefinition> entry : topologyTemplate.getCalculatedCapabilities().entrySet()) {
+
+                String instanceId = entry.getKey();
+                // capabilities of instance organized by type
+                Map<String, ListCapabilityDataDefinition> capsMapList = entry.getValue().getMapToscaDataDefinition();
+
+                if(capsMapList != null) {
+                    for (Entry<String, ListCapabilityDataDefinition> entryTypeList : capsMapList.entrySet()) {
+                        String capabilityType = entryTypeList.getKey();
+                        List<CapabilityDefinition> caps = entryTypeList.getValue().getListToscaDataDefinition().stream().map(cap -> mergeInstCapabiltyWithProperty(cap, instanceId, calculatedCapProperties)).collect(Collectors.toList());
+                        if (instancesCapabilities.containsKey(capabilityType)) {
+                            instancesCapabilities.get(capabilityType).addAll(caps);
+                        } else {
+                            instancesCapabilities.put(capabilityType, caps);
+                        }
+                        ComponentInstance instance = instancesMap.get(instanceId);
+                        if (instance == null) {
+                            log.error("instance is null for id {} entry {}", instanceId, entry.getValue().getToscaPresentationValue(JsonPresentationFields.NAME));
+                        } else {
+                            if (MapUtils.isEmpty(instance.getCapabilities())) {
+                                instance.setCapabilities(new HashMap<>());
+                            }
+                            instance.getCapabilities().put(capabilityType, new ArrayList<>(caps));
+                        }
+                    }
+                }
+            }
+            component.setCapabilities(instancesCapabilities);
+        }
+    }
+
+	private static void setCapabilitiesToComponentAndGroups(TopologyTemplate topologyTemplate, Component component) {
+
+		Map<String, MapCapabilityProperty> calculatedCapProperties = topologyTemplate.getCalculatedCapabilitiesProperties();
+
+		if (capabilitiesAndGroupsExist(topologyTemplate, component)) {
+			Map<String, GroupDefinition> groupsMap = component.getGroups().stream().collect(Collectors.toMap(GroupDefinition::getUniqueId,Function.identity()));
+
+			for (Map.Entry<String, MapListCapabilityDataDefinition> entry : topologyTemplate.getCalculatedCapabilities().entrySet()) {
+				findSetCapabilitiesToComponentAndGroup(calculatedCapProperties, component, groupsMap, entry);
 			}
-			CompositionDataDefinition compositionDataDefinition = compositions.get(JsonConstantKeysEnum.COMPOSITION.getValue());
-			if (compositionDataDefinition == null) {
-				compositionDataDefinition = new CompositionDataDefinition();
-				compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), compositionDataDefinition);
-			}
-
-			Map<String, RelationshipInstDataDefinition> relations = componentInstancesRelations.stream().flatMap(x -> convertRelationToToscaRelation(x).stream()).filter(i -> i.getUniqueId() != null)
-					.collect(Collectors.toMap(i -> i.getUniqueId(), i -> i));
-			compositionDataDefinition.setRelations(relations);
 		}
 	}
 
-	private static void convertInputs(Component component, TopologyTemplate topologyTemplate) {
-		List<InputDefinition> inputsList = component.getInputs();
-		if (inputsList != null && !inputsList.isEmpty()) {
-
-			Map<String, PropertyDataDefinition> inputsMap = inputsList.stream().map(i -> new PropertyDataDefinition(i)).collect(Collectors.toMap(i -> i.getName(), i -> i));
-			topologyTemplate.setInputs(inputsMap);
-		}
-
+	private static boolean capabilitiesAndGroupsExist(TopologyTemplate topologyTemplate, Component component) {
+		return MapUtils.isNotEmpty(topologyTemplate.getCalculatedCapabilities()) && CollectionUtils.isNotEmpty(component.getGroups());
 	}
 
-	private static void convertInputs(TopologyTemplate topologyTemplate, Component component) {
-		Map<String, PropertyDataDefinition> inputsMap = topologyTemplate.getInputs();
-		if (inputsMap != null && !inputsMap.isEmpty()) {
-			List<InputDefinition> inputsList = inputsMap.values().stream().map(i -> new InputDefinition(i)).collect(Collectors.toList());
-			component.setInputs(inputsList);
-		}
+	private static void findSetCapabilitiesToComponentAndGroup(Map<String, MapCapabilityProperty> calculatedCapProperties, Component component, Map<String, GroupDefinition> groupsMap, Map.Entry<String, MapListCapabilityDataDefinition> entry) {
 
+		String uniqueId = entry.getKey();
+		if(groupsMap.containsKey(uniqueId)){
+			setCapabilitiesToComponentAndGroup(calculatedCapProperties, component, entry, groupsMap.get(uniqueId));
+		} else {
+			log.warn("The group with uniqueId {} was not found", uniqueId);
+		}
 	}
 
-	private static void convertCommonToscaData(Component component, ToscaElement toscaElement) {
-		toscaElement.setUUID(component.getUUID());
-		toscaElement.setUniqueId(component.getUniqueId());
-		toscaElement.setSystemName(component.getSystemName());
-		toscaElement.setLifecycleState(component.getLifecycleState());
-		toscaElement.setComponentType(component.getComponentType());
-		toscaElement.setNormalizedName(component.getNormalizedName());
-		toscaElement.setMetadataValue(JsonPresentationFields.NAME, component.getName());
-		toscaElement.setCategories(component.getCategories());
-		toscaElement.setCreatorUserId(component.getCreatorUserId());
-		toscaElement.setCreationDate(component.getCreationDate());
-		toscaElement.setCreatorFullName(component.getCreatorFullName());
-		toscaElement.setHighestVersion(component.isHighestVersion());
-		toscaElement.setLastUpdateDate(component.getLastUpdateDate());
-		toscaElement.setLastUpdaterFullName(component.getLastUpdaterFullName());
-		toscaElement.setLastUpdaterUserId(component.getLastUpdaterUserId());
-		toscaElement.setDerivedFromGenericType(component.getDerivedFromGenericType());
-		toscaElement.setDerivedFromGenericVersion(component.getDerivedFromGenericVersion());
+	private static void setCapabilitiesToComponentAndGroup(Map<String, MapCapabilityProperty> calculatedCapProperties, Component component, Map.Entry<String, MapListCapabilityDataDefinition> entry, GroupDefinition group) {
 
-		toscaElement.setLifecycleState(component.getLifecycleState());
-		toscaElement.setMetadataValue(JsonPresentationFields.VERSION, component.getVersion());
-		if (component.getComponentType() == ComponentTypeEnum.RESOURCE) {
-			toscaElement.setMetadataValue(JsonPresentationFields.IS_ABSTRACT, ((Resource) component).isAbstract());
-			toscaElement.setMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME, ((Resource) component).getToscaResourceName());
-			toscaElement.setMetadataValue(JsonPresentationFields.VENDOR_NAME, ((Resource) component).getVendorName());
-			toscaElement.setMetadataValue(JsonPresentationFields.VENDOR_RELEASE, ((Resource) component).getVendorRelease());
-			// field isn't mandatory , but shouldn't be null(should be an empty string instead)
-			if (((Resource) component).getResourceVendorModelNumber() != null){
-				toscaElement.setMetadataValue(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER, ((Resource) component).getResourceVendorModelNumber());
+		for (Entry<String, ListCapabilityDataDefinition> entryTypeList : entry.getValue().getMapToscaDataDefinition().entrySet()) {
+			String capabilityType = entryTypeList.getKey();
+			List<CapabilityDefinition> caps = entryTypeList.getValue().getListToscaDataDefinition().stream().map(cap -> mergeInstCapabiltyWithProperty(cap, group.getUniqueId(), calculatedCapProperties)).collect(Collectors.toList());
+			if (component.getCapabilities().containsKey(capabilityType)) {
+				component.getCapabilities().get(capabilityType).addAll(caps);
 			} else {
-				toscaElement.setMetadataValue(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER, "");
+				component.getCapabilities().put(capabilityType, caps);
 			}
-		} else if (component.getComponentType() == ComponentTypeEnum.SERVICE) {
-			// field isn't mandatory , but shouldn't be null(should be an empty string instead)
-			if (((Service) component).getServiceType() != null){
-				toscaElement.setMetadataValue(JsonPresentationFields.SERVICE_TYPE, ((Service) component).getServiceType());
-			} else {
-				toscaElement.setMetadataValue(JsonPresentationFields.SERVICE_TYPE, "");
-			}
-			if (((Service) component).getServiceRole() != null){
-				toscaElement.setMetadataValue(JsonPresentationFields.SERVICE_ROLE, ((Service) component).getServiceRole());
-			} else {
-				toscaElement.setMetadataValue(JsonPresentationFields.SERVICE_ROLE, "");
-			}
-		}
-		toscaElement.setMetadataValue(JsonPresentationFields.CONFORMANCE_LEVEL, component.getConformanceLevel());
-		toscaElement.setMetadataValue(JsonPresentationFields.IS_DELETED, component.getIsDeleted());
-		toscaElement.setMetadataValue(JsonPresentationFields.ICON, component.getIcon());
-		toscaElement.setMetadataValue(JsonPresentationFields.DESCRIPTION, component.getDescription());
-		toscaElement.setMetadataValue(JsonPresentationFields.TAGS, component.getTags());
-		toscaElement.setMetadataValue(JsonPresentationFields.INVARIANT_UUID, component.getInvariantUUID());
-		toscaElement.setMetadataValue(JsonPresentationFields.CONTACT_ID, component.getContactId());
-	}
-
-	
-
-	private static void setComponentInstancesToComponent(TopologyTemplate topologyTemplate, Component component) {
-
-		List<ComponentInstance> componentInstances = new ArrayList<>();
-		ComponentInstance currComponentInstance;
-		for (Map.Entry<String, ComponentInstanceDataDefinition> entry : topologyTemplate.getComponentInstances().entrySet()) {
-			String key = entry.getKey();
-			currComponentInstance = new ComponentInstance(topologyTemplate.getComponentInstances().get(key));
-			if (topologyTemplate.getInstGroups() != null && topologyTemplate.getInstGroups().containsKey(key)) {
-				List<GroupInstance> groupInstances = topologyTemplate.getInstGroups().get(key).getMapToscaDataDefinition().entrySet().stream().map(e -> new GroupInstance(e.getValue())).collect(Collectors.toList());
-				currComponentInstance.setGroupInstances(groupInstances);
-			}
-			componentInstances.add(currComponentInstance);
-		}
-		component.setComponentInstances(componentInstances);
-	}
-
-	private static void setComponentInstancesInputsToComponent(TopologyTemplate topologyTemplate, Component component) {
-		if (topologyTemplate.getInstInputs() != null) {
-			Map<String, List<ComponentInstanceInput>> inputs = new HashMap<>();
-			for (Entry<String, MapPropertiesDataDefinition> entry : topologyTemplate.getInstInputs().entrySet()) {
-				if (entry.getValue() != null && entry.getValue().getMapToscaDataDefinition() != null) {
-					String key = entry.getKey();
-					List<ComponentInstanceInput> componentInstanceAttributes = entry.getValue().getMapToscaDataDefinition().entrySet().stream().map(e -> new ComponentInstanceInput(e.getValue())).collect(Collectors.toList());
-					inputs.put(key, componentInstanceAttributes);
-				}
-			}
-			component.setComponentInstancesInputs(inputs);
+			group.getCapabilities().put(capabilityType, Lists.newArrayList(caps));
 		}
 	}
 
-	private static void setComponentInstancesPropertiesToComponent(TopologyTemplate topologyTemplate, Component component) {
-		if (topologyTemplate.getInstProperties() != null) {
-			Map<String, List<ComponentInstanceProperty>> properties = new HashMap<>();
-			for (Entry<String, MapPropertiesDataDefinition> entry : topologyTemplate.getInstProperties().entrySet()) {
-				if (entry.getValue() != null && entry.getValue().getMapToscaDataDefinition() != null) {
-					String key = entry.getKey();
-					List<ComponentInstanceProperty> componentInstanceAttributes = entry.getValue().getMapToscaDataDefinition().entrySet().stream().map(e -> new ComponentInstanceProperty(new PropertyDefinition(e.getValue())))
-							.collect(Collectors.toList());
-					properties.put(key, componentInstanceAttributes);
-				}
-			}
-			component.setComponentInstancesProperties(properties);
-		}
-	}
-
-	private static void setComponentInstancesAttributesToComponent(TopologyTemplate topologyTemplate, Component component) {
-		if (topologyTemplate.getInstAttributes() != null) {
-			Map<String, List<ComponentInstanceProperty>> attributes = new HashMap<>();
-			for (Map.Entry<String, MapPropertiesDataDefinition> entry : topologyTemplate.getInstAttributes().entrySet()) {
-				if (entry.getValue() != null && entry.getValue().getMapToscaDataDefinition() != null) {
-					String key = entry.getKey();
-					List<ComponentInstanceProperty> componentInstanceAttributes = entry.getValue().getMapToscaDataDefinition().entrySet().stream().map(e -> new ComponentInstanceProperty(new ComponentInstanceProperty(e.getValue())))
-							.collect(Collectors.toList());
-					attributes.put(key, componentInstanceAttributes);
-				}
-			}
-			component.setComponentInstancesAttributes(attributes);
-		}
-	}
-
-	private static void setComponentInstancesRequirementsToComponent(TopologyTemplate topologyTemplate, Component component) {
-
-		if (topologyTemplate.getCalculatedRequirements() != null) {
-			// Requirements of component organized by capability
-			Map<String, List<RequirementDefinition>> instancesRequirements = new HashMap<>();
-
-			Map<String, ComponentInstance> instancesMap = new HashMap<>();
-			for (ComponentInstance currInstance : component.getComponentInstances()) {
-				instancesMap.put(currInstance.getUniqueId(), currInstance);
-			}
-			for (Map.Entry<String, MapListRequirementDataDefinition> entry : topologyTemplate.getCalculatedRequirements().entrySet()) {
-
-				String instanceId = entry.getKey();
-				// Requirements of instance organized by capability
-				Map<String, ListRequirementDataDefinition> capsMapList = entry.getValue().getMapToscaDataDefinition();
-
-				for (Entry<String, ListRequirementDataDefinition> entryTypeList : capsMapList.entrySet()) {
-					String capabilityType = entryTypeList.getKey();
-					List<RequirementDefinition> caps = entryTypeList.getValue().getListToscaDataDefinition().stream().map(cap -> new RequirementDefinition(cap)).collect(Collectors.toList());
-					if (instancesRequirements.containsKey(capabilityType)) {
-						instancesRequirements.get(capabilityType).addAll(caps);
-					} else {
-						instancesRequirements.put(capabilityType, caps);
-					}
-					if (MapUtils.isEmpty(instancesMap.get(instanceId).getRequirements())) {
-						instancesMap.get(instanceId).setRequirements(new HashMap<>());
-					}
-					instancesMap.get(instanceId).getRequirements().put(capabilityType, new ArrayList<>(caps));
-				}
-			}
-			component.setRequirements(instancesRequirements);
-		}
-	}
-
-	private static void setComponentInstancesCapabilitiesToComponentAndCI(TopologyTemplate topologyTemplate, Component component) {
-		Map<String, MapCapabiltyProperty> calculatedCapProperties = topologyTemplate.getCalculatedCapabilitiesProperties();
-
-		if (topologyTemplate.getCalculatedCapabilities() != null) {
-			// capabilities of component organized by type
-			Map<String, List<CapabilityDefinition>> instancesCapabilities = new HashMap<>();
-
-			Map<String, ComponentInstance> instancesMap = new HashMap<>();
-			for (ComponentInstance currInstance : component.getComponentInstances()) {
-				instancesMap.put(currInstance.getUniqueId(), currInstance);
-			}
-			for (Map.Entry<String, MapListCapabiltyDataDefinition> entry : topologyTemplate.getCalculatedCapabilities().entrySet()) {
-
-				String instanceId = entry.getKey();
-				// capabilities of instance organized by type
-				Map<String, ListCapabilityDataDefinition> capsMapList = entry.getValue().getMapToscaDataDefinition();
-
-				for (Entry<String, ListCapabilityDataDefinition> entryTypeList : capsMapList.entrySet()) {
-					String capabilityType = entryTypeList.getKey();
-					List<CapabilityDefinition> caps = entryTypeList.getValue().getListToscaDataDefinition().stream().map(cap -> mergeInstCapabiltyWithProperty(cap, instanceId, calculatedCapProperties)).collect(Collectors.toList());
-					if (instancesCapabilities.containsKey(capabilityType)) {
-						instancesCapabilities.get(capabilityType).addAll(caps);
-					} else {
-						instancesCapabilities.put(capabilityType, caps);
-					}
-					ComponentInstance instance = instancesMap.get(instanceId);
-					if (instance == null) {
-						log.error("instance is null for id {} entry {}", instanceId, entry.getValue().getToscaPresentationValue(JsonPresentationFields.NAME));
-					} else {
-						if (MapUtils.isEmpty(instance.getCapabilities())) {
-							instance.setCapabilities(new HashMap<>());
-						}
-						instance.getCapabilities().put(capabilityType, new ArrayList<>(caps));
-					}
-				}
-			}
-			component.setCapabilities(instancesCapabilities);
-		}
-	}
-
-	private static CapabilityDefinition mergeInstCapabiltyWithProperty(CapabilityDataDefinition cap, String instance, Map<String, MapCapabiltyProperty> calculatedCapProperties) {
-		CapabilityDefinition capability = new CapabilityDefinition(cap);
-		if (calculatedCapProperties != null) {
-			MapCapabiltyProperty mapOfMapPropertiesDataDefinition = calculatedCapProperties.get(instance);
-			if (mapOfMapPropertiesDataDefinition != null && mapOfMapPropertiesDataDefinition.getMapToscaDataDefinition() != null) {
-
-				Map<String, MapPropertiesDataDefinition> toscaCapPropMap = mapOfMapPropertiesDataDefinition.getMapToscaDataDefinition();
-				toscaCapPropMap.forEach(new BiConsumer<String, MapPropertiesDataDefinition>() {
-					@Override
-					public void accept(String s, MapPropertiesDataDefinition capProp) {
-						// format key of capability properties :
-						// VF instance in service : instanceId#ownerId#type#capName
-						// VFC instance ion VF : instanceId#type#capName -> instanceId=ownerId
-						String[] result = s.split(CAP_PROP_DELIM);
-						if (result.length < 4) {
-							log.debug("wrong key format for capabilty, key {}", capProp);
-							return;
-						}
-						int instanceIndex = 0;
-						int ownerIndex = 1;
-						int typeIndex = result.length - 2;
-						int nameIndex = result.length - 1;
-						if (capProp != null) {
-							if (result[typeIndex].equals(cap.getType()) && result[nameIndex].equals(cap.getName()) && cap.getOwnerId().equals(result[ownerIndex]) && instance.equals(result[instanceIndex])) {
-
-								Map<String, PropertyDataDefinition> capMap = capProp.getMapToscaDataDefinition();
-
-								if (capMap != null && !capMap.isEmpty()) {
-									// List<PropertyDataDefinition> list = map.values().stream().collect(Collectors.toList());
-									List<ComponentInstanceProperty> capPropsList = capMap.values().stream().map(o -> {
-
-										return new ComponentInstanceProperty(o);
-									}).collect(Collectors.toList());
-
-									capability.setProperties(capPropsList);
-								}
-							}
-						}
-					}
-				});
+	private static CapabilityDefinition mergeInstCapabiltyWithProperty(CapabilityDataDefinition cap, String ownerId, Map<String, MapCapabilityProperty> calculatedCapProperties) {
+        CapabilityDefinition capability = new CapabilityDefinition(cap);
+        if (calculatedCapProperties != null) {
+			MapCapabilityProperty mapOfMapPropertiesDataDefinition = calculatedCapProperties.get(ownerId);
+            if (mapOfMapPropertiesDataDefinition != null && mapOfMapPropertiesDataDefinition.getMapToscaDataDefinition() != null) {
+                Map<String, MapPropertiesDataDefinition> toscaCapPropMap = mapOfMapPropertiesDataDefinition.getMapToscaDataDefinition();
+				toscaCapPropMap.forEach(( keyPath,  capProp)-> findConvertSetProperties(cap, ownerId, capability, keyPath, capProp));
 			}
 		}
 		return capability;
 	}
 
-	private static void setComponentInstancesToTopologyTemplate(Component component, TopologyTemplate topologyTemplate) {
-
-		Map<String, ComponentInstanceDataDefinition> componentInstances = new HashMap<>();
-		ComponentInstanceDataDefinition convertedInstance;
-		if (component.getComponentInstances() != null) {
-			for (ComponentInstance instance : component.getComponentInstances()) {
-				convertedInstance = new ComponentInstanceDataDefinition(instance);
-				if (instance.getGroupInstances() != null) {
-					MapGroupsDataDefinition groupsMap = new MapGroupsDataDefinition();
-
-					groupsMap.setMapToscaDataDefinition(instance.getGroupInstances().stream().map(e -> new GroupInstanceDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
-					if (topologyTemplate.getInstGroups() == null) {
-						topologyTemplate.setInstGroups(new HashMap<>());
-					}
-					topologyTemplate.getInstGroups().put(instance.getUniqueId(), groupsMap);
-				}
-				componentInstances.put(instance.getUniqueId(), convertedInstance);
-			}
+	private static void findConvertSetProperties(CapabilityDataDefinition cap, String primaryPathKey, CapabilityDefinition capability, String path, MapPropertiesDataDefinition capProp) {
+		// format key of capability properties :
+		// VF instance in service : instanceId#ownerId#type#capName
+		// VFC instance in VF : instanceId#type#capName -> instanceId=ownerId
+		// Group in service : groupName#ownerId#type#capName
+		// Group in VF : groupName#type#capName -> groupName=ownerId
+		String[] result = path.split(CAP_PROP_DELIM);
+		if (result.length < 4) {
+			log.debug("wrong key format for capabilty, key {}", capProp);
+			return;
 		}
-		topologyTemplate.setComponentInstances(componentInstances);
-
-	}
-
-	private static void setComponentInstancesInputsToTopologyTemplate(Component component, TopologyTemplate topologyTemplate) {
-
-		if (component.getComponentInstancesInputs() != null) {
-			topologyTemplate.setInstInputs(new HashMap<>());
-			MapPropertiesDataDefinition inputsMap;
-			for (Entry<String, List<ComponentInstanceInput>> entry : component.getComponentInstancesInputs().entrySet()) {
-				inputsMap = new MapPropertiesDataDefinition();
-
-				inputsMap.setMapToscaDataDefinition(entry.getValue().stream().map(e -> new PropertyDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
-
-				topologyTemplate.getInstInputs().put(entry.getKey(), inputsMap);
-			}
+		if (relatedPropertiesExist(cap, primaryPathKey, capProp, result)) {
+			capability.setProperties(capProp.getMapToscaDataDefinition().values().stream().map(ComponentInstanceProperty::new).collect(Collectors.toList()));
 		}
 	}
 
-	private static void setComponentInstancesPropertiesToTopologyTemplate(Component component, TopologyTemplate topologyTemplate) {
-
-		if (component.getComponentInstancesProperties() != null) {
-			topologyTemplate.setInstProperties(new HashMap<>());
-			MapPropertiesDataDefinition propertiesMap;
-			for (Entry<String, List<ComponentInstanceProperty>> entry : component.getComponentInstancesProperties().entrySet()) {
-				propertiesMap = new MapPropertiesDataDefinition();
-
-				propertiesMap.setMapToscaDataDefinition(entry.getValue().stream().map(e -> new PropertyDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
-
-				topologyTemplate.getInstProperties().put(entry.getKey(), propertiesMap);
-			}
-		}
+	private static boolean relatedPropertiesExist(CapabilityDataDefinition cap, String primaryPathKey,	MapPropertiesDataDefinition capProp, String[] result) {
+		return capProp != null && MapUtils.isNotEmpty(capProp.getMapToscaDataDefinition()) && areRelatedProperties(cap, primaryPathKey, result);
 	}
 
-	private static void setComponentInstancesArtifactsToTopologyTemplate(Component component, TopologyTemplate topologyTemplate) {
+	private static boolean areRelatedProperties(CapabilityDataDefinition cap, String primaryPathKey, String[] result) {
+		int primaryKeyIndex = 0;
+		int ownerIndex = 1;
+		int typeIndex = result.length - 2;
+		int nameIndex = result.length - 1;
+		return result[typeIndex].equals(cap.getType()) && result[nameIndex].equals(cap.getName()) && cap.getOwnerId().equals(result[ownerIndex]) && primaryPathKey.equals(result[primaryKeyIndex]);
+    }
 
-		List<ComponentInstance> componentInstances = component.getComponentInstances();
-		if (componentInstances != null) {
-			topologyTemplate.setInstanceArtifacts(new HashMap<>());
-			topologyTemplate.setInstDeploymentArtifacts(new HashMap<>());
+    private static void setComponentInstancesToTopologyTemplate(Component component, TopologyTemplate topologyTemplate) {
 
-			for (ComponentInstance ci : componentInstances) {
-				Map<String, ArtifactDefinition> artifacts = ci.getArtifacts();
-				if (artifacts != null) {
-					Map<String, ArtifactDataDefinition> mapToscaDataDefinitionArtifact = artifacts.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> new ArtifactDataDefinition(e.getValue()))); 
-					MapArtifactDataDefinition insArtifact = new MapArtifactDataDefinition(mapToscaDataDefinitionArtifact);
-					topologyTemplate.getInstanceArtifacts().put(ci.getUniqueId(), insArtifact);
-				}
-				
-				Map<String, ArtifactDefinition> deplArtifacts = ci.getDeploymentArtifacts();
-				if (deplArtifacts != null) {
-					Map<String, ArtifactDataDefinition> mapToscaDataDefinitionDepArtifact = deplArtifacts.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> new ArtifactDataDefinition(e.getValue())));
-					MapArtifactDataDefinition insDepArtifact = new MapArtifactDataDefinition(mapToscaDataDefinitionDepArtifact);
-					topologyTemplate.getInstDeploymentArtifacts().put(ci.getUniqueId(), insDepArtifact);
-				}
-			}
-		}
+        Map<String, ComponentInstanceDataDefinition> componentInstances = new HashMap<>();
+        ComponentInstanceDataDefinition convertedInstance;
+        if (component.getComponentInstances() != null) {
+            for (ComponentInstance instance : component.getComponentInstances()) {
+                convertedInstance = new ComponentInstanceDataDefinition(instance);
+                if (instance.getGroupInstances() != null) {
+                    MapGroupsDataDefinition groupsMap = new MapGroupsDataDefinition();
+
+					groupsMap.setMapToscaDataDefinition(instance.getGroupInstances().stream().map(GroupInstanceDataDefinition::new).collect(Collectors.toMap(GroupInstanceDataDefinition::getName, Function.identity())));
+                    if (topologyTemplate.getInstGroups() == null) {
+                        topologyTemplate.setInstGroups(new HashMap<>());
+                    }
+                    topologyTemplate.getInstGroups().put(instance.getUniqueId(), groupsMap);
+                }
+                componentInstances.put(instance.getUniqueId(), convertedInstance);
+            }
+        }
+        topologyTemplate.setComponentInstances(componentInstances);
+
+    }
+
+    private static void setComponentInstancesInputsToTopologyTemplate(Component component, TopologyTemplate topologyTemplate) {
+
+        if (component.getComponentInstancesInputs() != null) {
+            topologyTemplate.setInstInputs(new HashMap<>());
+            MapPropertiesDataDefinition inputsMap;
+            for (Entry<String, List<ComponentInstanceInput>> entry : component.getComponentInstancesInputs().entrySet()) {
+                inputsMap = new MapPropertiesDataDefinition();
+
+				inputsMap.setMapToscaDataDefinition(entry.getValue().stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, Function.identity())));
+
+                topologyTemplate.getInstInputs().put(entry.getKey(), inputsMap);
+            }
+        }
+    }
+
+    private static void setComponentInstancesPropertiesToTopologyTemplate(Component component, TopologyTemplate topologyTemplate) {
+
+        if (component.getComponentInstancesProperties() != null) {
+            topologyTemplate.setInstProperties(new HashMap<>());
+            MapPropertiesDataDefinition propertiesMap;
+            for (Entry<String, List<ComponentInstanceProperty>> entry : component.getComponentInstancesProperties().entrySet()) {
+                propertiesMap = new MapPropertiesDataDefinition();
+
+				propertiesMap.setMapToscaDataDefinition(entry.getValue().stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, Function.identity())));
+
+                topologyTemplate.getInstProperties().put(entry.getKey(), propertiesMap);
+            }
+        }
+    }
+
+    private static void setComponentInstancesArtifactsToTopologyTemplate(Component component, TopologyTemplate topologyTemplate) {
+
+        List<ComponentInstance> componentInstances = component.getComponentInstances();
+        if (componentInstances != null) {
+            topologyTemplate.setInstanceArtifacts(new HashMap<>());
+            topologyTemplate.setInstDeploymentArtifacts(new HashMap<>());
+
+            for (ComponentInstance ci : componentInstances) {
+                Map<String, ArtifactDefinition> artifacts = ci.getArtifacts();
+                if (artifacts != null) {
+					Map<String, ArtifactDataDefinition> mapToscaDataDefinitionArtifact = artifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
+                    MapArtifactDataDefinition insArtifact = new MapArtifactDataDefinition(mapToscaDataDefinitionArtifact);
+                    topologyTemplate.getInstanceArtifacts().put(ci.getUniqueId(), insArtifact);
+                }
+
+                Map<String, ArtifactDefinition> deplArtifacts = ci.getDeploymentArtifacts();
+                if (deplArtifacts != null) {
+					Map<String, ArtifactDataDefinition> mapToscaDataDefinitionDepArtifact = deplArtifacts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
+                    MapArtifactDataDefinition insDepArtifact = new MapArtifactDataDefinition(mapToscaDataDefinitionDepArtifact);
+                    topologyTemplate.getInstDeploymentArtifacts().put(ci.getUniqueId(), insDepArtifact);
+                }
+            }
+        }
+    }
+
+    private static void setComponentInstancesAttributesToTopologyTemplate(Component component, TopologyTemplate topologyTemplate) {
+
+        if (component.getComponentInstancesAttributes() != null) {
+            topologyTemplate.setInstAttributes(new HashMap<>());
+            MapPropertiesDataDefinition attributesMap;
+            for (Entry<String, List<ComponentInstanceProperty>> entry : component.getComponentInstancesAttributes().entrySet()) {
+                attributesMap = new MapPropertiesDataDefinition();
+
+				attributesMap.setMapToscaDataDefinition(entry.getValue().stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, Function.identity())));
+
+                topologyTemplate.getInstAttributes().put(entry.getKey(), attributesMap);
+            }
+        }
+    }
+
+    public static ComponentMetadataData convertToComponentMetadata(GraphVertex vertex) {
+        ComponentMetadataData metadata = null;
+        switch (vertex.getType()) {
+        case SERVICE:
+            metadata = new ServiceMetadataData(vertex.getMetadataJson());
+            break;
+        case RESOURCE:
+            metadata = new ResourceMetadataData(vertex.getMetadataJson());
+            break;
+        case PRODUCT:
+            metadata = new ProductMetadataData(vertex.getMetadataJson());
+            break;
+        default:
+            break;
+        }
+        if (metadata != null) {
+            metadata.getMetadataDataDefinition().setUniqueId(vertex.getUniqueId());
+            metadata.getMetadataDataDefinition().setLastUpdateDate((Long) vertex.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE));
+            metadata.getMetadataDataDefinition().setUUID((String) vertex.getJsonMetadataField(JsonPresentationFields.UUID));
+            metadata.getMetadataDataDefinition().setState((String) vertex.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE));
+        }
+        return metadata;
+    }
+
+    public static List<GroupDefinition> convertToGroupDefinitions(Map<String, GroupDataDefinition> groups) {
+
+        List<GroupDefinition> groupDefinitions = null;
+        if (MapUtils.isNotEmpty(groups)) {
+			groupDefinitions = groups.values().stream().map(GroupDefinition::new).collect(Collectors.toList());
+        }
+        return groupDefinitions;
 	}
 
-	private static void setComponentInstancesAttributesToTopologyTemplate(Component component, TopologyTemplate topologyTemplate) {
-
-		if (component.getComponentInstancesAttributes() != null) {
-			topologyTemplate.setInstAttributes(new HashMap<>());
-			MapPropertiesDataDefinition attributesMap;
-			for (Entry<String, List<ComponentInstanceProperty>> entry : component.getComponentInstancesAttributes().entrySet()) {
-				attributesMap = new MapPropertiesDataDefinition();
-
-				attributesMap.setMapToscaDataDefinition(entry.getValue().stream().map(e -> new PropertyDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
-
-				topologyTemplate.getInstAttributes().put(entry.getKey(), attributesMap);
-			}
-		}
+	public static Map<String, MapCapabilityProperty> extractCapabilityProperteisFromInstances(List<ComponentInstance> instances, boolean fromCsar) {
+		return instances
+				.stream()
+				.collect(Collectors.toMap(ComponentInstanceDataDefinition::getUniqueId,
+						ci -> convertToMapOfMapCapabiltyProperties(ci.getCapabilities(), ci.getUniqueId(), fromCsar)));
 	}
 
-	public static ComponentMetadataData convertToComponentMetadata(GraphVertex vertex) {
-		ComponentMetadataData metadata = null;
-		switch (vertex.getType()) {
-		case SERVICE:
-			metadata = new ServiceMetadataData(vertex.getMetadataJson());
-			break;
-		case RESOURCE:
-			metadata = new ResourceMetadataData(vertex.getMetadataJson());
-			break;
-		case PRODUCT:
-			metadata = new ProductMetadataData(vertex.getMetadataJson());
-			break;
-		default:
-			break;
-		}
-		if (metadata != null) {
-			metadata.getMetadataDataDefinition().setUniqueId(vertex.getUniqueId());
-			metadata.getMetadataDataDefinition().setLastUpdateDate((Long) vertex.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE));
-			metadata.getMetadataDataDefinition().setUUID((String) vertex.getJsonMetadataField(JsonPresentationFields.UUID));
-			metadata.getMetadataDataDefinition().setState((String) vertex.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE));
-		}
-		return metadata;
+	public static Map<String, MapCapabilityProperty> extractCapabilityPropertiesFromGroups(List<GroupDefinition> groups, boolean fromCsar) {
+		if(CollectionUtils.isNotEmpty(groups))
+			return groups
+				.stream()
+				.collect(Collectors.toMap(GroupDefinition::getUniqueId,
+						g -> convertToMapOfMapCapabiltyProperties(g.getCapabilities(), g.getUniqueId(), fromCsar)));
+		return Maps.newHashMap();
 	}
 
-	public static List<GroupDefinition> convertToGroupDefinitions(Map<String, GroupDataDefinition> groups) {
-
-		List<GroupDefinition> groupDefinitions = null;
-		if (MapUtils.isNotEmpty(groups)) {
-			groupDefinitions = groups.values().stream().map(g -> new GroupDefinition(g)).collect(Collectors.toList());
+	public static Map<String, MapListCapabilityDataDefinition> extractCapabilitiesFromGroups(final List<GroupDefinition> groupDefinitions) {
+		Map<String, MapListCapabilityDataDefinition> calculatedCapabilities = Maps.newHashMap();
+		for(GroupDefinition groupDefinition :groupDefinitions){
+			calculatedCapabilities.put(groupDefinition.getUniqueId(), new MapListCapabilityDataDefinition(buildMapOfListsOfCapabilities(groupDefinition)));
 		}
-		return groupDefinitions;
+		return calculatedCapabilities;
 	}
 
+	public static Map<String, ListCapabilityDataDefinition> buildMapOfListsOfCapabilities(GroupDefinition groupDefinition) {
+		return groupDefinition.getCapabilities().entrySet()
+				.stream()
+				.collect(Collectors.toMap(Map.Entry::getKey, e-> new ListCapabilityDataDefinition(e.getValue()
+						.stream()
+						.map(CapabilityDataDefinition::new)
+						.collect(Collectors.toList()))));
+    }
+
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/normatives/ToscaTypeMetadata.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/normatives/ToscaTypeMetadata.java
new file mode 100644
index 0000000..d86cb7e
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/normatives/ToscaTypeMetadata.java
@@ -0,0 +1,31 @@
+package org.openecomp.sdc.be.model.normatives;
+
+public class ToscaTypeMetadata {
+
+    private String icon;
+    private String displayName;
+
+    public ToscaTypeMetadata() {
+    }
+
+    public ToscaTypeMetadata(String icon, String displayName) {
+        this.icon = icon;
+        this.displayName = displayName;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/StorageException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/StorageException.java
index de52101..40c39f3 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/StorageException.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/StorageException.java
@@ -1,17 +1,36 @@
 package org.openecomp.sdc.be.model.operations;
 
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 
 public class StorageException extends RuntimeException{
 
     private final StorageOperationStatus storageOperationStatus;
+    private final String[] params;
 
-    public StorageException(StorageOperationStatus storageOperationStatus) {
+    public StorageException(StorageOperationStatus storageOperationStatus, String... params) {
         super();
         this.storageOperationStatus = storageOperationStatus;
+        this.params = params;
+    }
+
+    public StorageException(String message, Throwable cause, TitanOperationStatus titanOperationStatus, String... params){
+        super(message, cause);
+        storageOperationStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus);
+        this.params = params;
+    }
+
+    public StorageException(TitanOperationStatus titanOperationStatus, String... params) {
+        storageOperationStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus);
+        this.params = params;
     }
 
     public StorageOperationStatus getStorageOperationStatus() {
         return storageOperationStatus;
     }
+
+    public String[] getParams() {
+        return params.clone();
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/DerivedFromOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/DerivedFromOperation.java
index 73abef3..d0ac054 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/DerivedFromOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/DerivedFromOperation.java
@@ -1,10 +1,12 @@
 package org.openecomp.sdc.be.model.operations.api;
 
+
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 
-import fj.data.Either;
+import java.util.function.Function;
 
 public interface DerivedFromOperation {
 
@@ -16,7 +18,7 @@
      * @return the status of the operation
      */
     Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(String parentUniqueId, String derivedFromUniqueId, NodeTypeEnum nodeType);
-
+    
     /**
      *
      * @param uniqueId the id of the entity of which to fetch its derived from object
@@ -34,4 +36,19 @@
      * @return the status of the remove operation. if no derived from relation exists the operation is successful.
      */
     StorageOperationStatus removeDerivedFromRelation(String uniqueId, String derivedFromUniqueId, NodeTypeEnum nodeType);
+    
+    
+    /**
+     * Checks whether childCandidateType is derived from parentCandidateType
+     */
+    public <T extends GraphNode> Either<Boolean, StorageOperationStatus> isTypeDerivedFrom(String childCandidateType, String parentCandidateType, String currentChildType,
+                                                                                           NodeTypeEnum capabilitytype, Class<T> clazz,
+                                                                                           Function<T, String> typeProvider);
+
+    /**
+     * Checks whether replacement of oldTypeParent hold in DERIVED FROM with newTypeParent is legal
+     */
+    public <T extends GraphNode> StorageOperationStatus isUpdateParentAllowed(String oldTypeParent, String newTypeParent, String childType,
+                                                                               NodeTypeEnum capabilitytype, Class<T> clazz,
+                                                                               Function<T, String> typeProvider);        
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.java
index 9036c62..3fb58a0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.java
@@ -20,56 +20,54 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.List;
-
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterInfo;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
 import org.openecomp.sdc.be.resources.data.AdditionalInfoParameterData;
 
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.util.List;
 
 public interface IAdditionalInformationOperation {
 
-	public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String key, String value);
+    public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String key, String value);
 
-	public Either<AdditionalInformationDefinition, TitanOperationStatus> updateAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String origKey, String key, String value);
+    public Either<AdditionalInformationDefinition, TitanOperationStatus> updateAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String origKey, String key, String value);
 
-	public Either<AdditionalInformationDefinition, TitanOperationStatus> deleteAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String key);
+    public Either<AdditionalInformationDefinition, TitanOperationStatus> deleteAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String key);
 
-	public Either<AdditionalInfoParameterData, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String resourceUniqueId);
+    public Either<AdditionalInfoParameterData, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String resourceUniqueId);
 
-	public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters);
+    public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters);
 
-	public TitanOperationStatus findResourceAllAdditionalInformationRecursively(String uniqueId, List<AdditionalInformationDefinition> properties);
+    public TitanOperationStatus findResourceAllAdditionalInformationRecursively(String uniqueId, List<AdditionalInformationDefinition> properties);
 
-	public TitanOperationStatus findServiceAllAdditionalInformationRecursively(String uniqueId, List<AdditionalInformationDefinition> properties);
+    public TitanOperationStatus findServiceAllAdditionalInformationRecursively(String uniqueId, List<AdditionalInformationDefinition> properties);
 
-	public Either<AdditionalInformationDefinition, StorageOperationStatus> createAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String key, String value, boolean inTransaction);
+    public Either<AdditionalInformationDefinition, StorageOperationStatus> createAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String key, String value, boolean inTransaction);
 
-	public Either<AdditionalInformationDefinition, StorageOperationStatus> updateAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, String key, String value, boolean inTransaction);
+    public Either<AdditionalInformationDefinition, StorageOperationStatus> updateAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, String key, String value, boolean inTransaction);
 
-	public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction);
+    public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction);
 
-	public Either<Integer, StorageOperationStatus> getNumberOfAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean inTransaction);
+    public Either<Integer, StorageOperationStatus> getNumberOfAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean inTransaction);
 
-	public Either<Integer, TitanOperationStatus> getNumberOfParameters(NodeTypeEnum nodeType, String resourceId);
+    public Either<Integer, TitanOperationStatus> getNumberOfParameters(NodeTypeEnum nodeType, String resourceId);
 
-	public Either<AdditionalInfoParameterInfo, TitanOperationStatus> getAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id);
+    public Either<AdditionalInfoParameterInfo, TitanOperationStatus> getAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id);
 
-	public Either<AdditionalInfoParameterInfo, StorageOperationStatus> getAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction);
+    public Either<AdditionalInfoParameterInfo, StorageOperationStatus> getAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction);
 
-	public Either<AdditionalInformationDefinition, TitanOperationStatus> getAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification);
+    public Either<AdditionalInformationDefinition, TitanOperationStatus> getAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification);
 
-	public Either<AdditionalInformationDefinition, StorageOperationStatus> getAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification, boolean inTransaction);
+    public Either<AdditionalInformationDefinition, StorageOperationStatus> getAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification, boolean inTransaction);
 
-	public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean inTransaction);
+    public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean inTransaction);
 
-	public Either<TitanVertex, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, TitanVertex matadatVertex);
+    public Either<TitanVertex, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, TitanVertex matadatVertex);
 
-	public TitanOperationStatus addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters, TitanVertex metadataVertex);
+    public TitanOperationStatus addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters, TitanVertex metadataVertex);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java
index 5393dbe..e1b04e9 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java
@@ -20,25 +20,23 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.Map;
-
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.ArtifactDefinition;
 
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.util.Map;
 
 public interface IArtifactOperation {
 
-	public Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfExist, boolean inTransaction);
+    public Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfExist, boolean inTransaction);
 
-	public Either<ArtifactDefinition, StorageOperationStatus> updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, boolean inTransaction);
+    public Either<ArtifactDefinition, StorageOperationStatus> updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, boolean inTransaction);
 
-	public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum resource, boolean deleteMandatoryArtifact, boolean inTransaction);
+    public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum resource, boolean deleteMandatoryArtifact, boolean inTransaction);
 
-	public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction);
+    public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction);
 
-	public StorageOperationStatus addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, TitanVertex parentVertex);
+    public StorageOperationStatus addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, TitanVertex parentVertex);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.java
index 6b5a143..fcf5fab 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.java
@@ -27,15 +27,15 @@
  */
 public interface ICacheMangerOperation {
 
-	/**
-	 * 
-	 * 
-	 * @param componentId
-	 * @param timestamp
-	 * @param nodeTypeEnum
-	 */
-	void updateComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum);
+    /**
+     *
+     *
+     * @param componentId
+     * @param timestamp
+     * @param nodeTypeEnum
+     */
+    void updateComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum);
 
-	void storeComponentInCache(org.openecomp.sdc.be.model.Component component, NodeTypeEnum nodeTypeEnum);
+    void storeComponentInCache(org.openecomp.sdc.be.model.Component component, NodeTypeEnum nodeTypeEnum);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.java
index 96c0e7e..da059fe 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.java
@@ -20,18 +20,14 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.List;
-import java.util.Map;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 
-import fj.data.Either;
+import java.util.Map;
 
 public interface ICapabilityOperation {
 
-	Either<Map<String, PropertyDefinition>, TitanOperationStatus> getAllCapabilityTypePropertiesFromAllDerivedFrom(String firstParentType);
-
-	Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertyUniqueness(Map<String, PropertyDefinition> propertiesOfCapabilityType, List<PropertyDefinition> properties);
+    Either<Map<String, PropertyDefinition>, TitanOperationStatus> getAllCapabilityTypePropertiesFromAllDerivedFrom(String firstParentType);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java
index fa06b46..7f8e07e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java
@@ -20,25 +20,27 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
-
 import fj.data.Either;
+import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
 
 public interface ICapabilityTypeOperation {
 
-	/**
-	 * @param capabilityTypeDefinition
-	 * @return
-	 */
-	public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition);
+    /**
+     * @param capabilityTypeDefinition
+     * @return
+     */
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition);
 
-	public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction);
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction);
+    
+    
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> updateCapabilityType(CapabilityTypeDefinition capabilityTypeDefNew, CapabilityTypeDefinition capabilityTypeDefOld);
 
-	/**
-	 * @param uniqueId
-	 * @return
-	 */
-	public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId);
+    /**
+     * @param uniqueId
+     * @return
+     */
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId);
 
-	public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, boolean inTransaction);
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, boolean inTransaction);
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java
index 90e01c3..0b2807a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java
@@ -20,6 +20,7 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.ComponentInstance;
@@ -27,46 +28,44 @@
 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
 
-import fj.data.Either;
-
 public interface IComponentInstanceOperation {
 
-	public Either<Integer, StorageOperationStatus> increaseAndGetResourceInstanceSpecificCounter(String resourceInstanceId, GraphPropertiesDictionary counterType, boolean inTransaction);
+    public Either<Integer, StorageOperationStatus> increaseAndGetResourceInstanceSpecificCounter(String resourceInstanceId, GraphPropertiesDictionary counterType, boolean inTransaction);
 
-	/**
-	 * Adds Attribute to resource instance
-	 * 
-	 * @param resourceInstanceAttribute
-	 *            * @param resourceInstanceId * @param index * @param inTransaction
-	 * @return
-	 **/
-	public Either<ComponentInstanceProperty, StorageOperationStatus> addAttributeValueToResourceInstance(ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId, Integer index, boolean inTransaction);
+    /**
+     * Adds Attribute to resource instance
+     *
+     * @param resourceInstanceAttribute
+     *            * @param resourceInstanceId * @param index * @param inTransaction
+     * @return
+     **/
+    public Either<ComponentInstanceProperty, StorageOperationStatus> addAttributeValueToResourceInstance(ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId, Integer index, boolean inTransaction);
 
-	/**
-	 * Updates Attribute on resource instance
-	 * 
-	 * @param attribute
-	 * @param resourceInstanceId
-	 * @param inTransaction
-	 * @return
-	 */
-	public Either<ComponentInstanceProperty, StorageOperationStatus> updateAttributeValueInResourceInstance(ComponentInstanceProperty attribute, String resourceInstanceId, boolean inTransaction);
+    /**
+     * Updates Attribute on resource instance
+     *
+     * @param attribute
+     * @param resourceInstanceId
+     * @param inTransaction
+     * @return
+     */
+    public Either<ComponentInstanceProperty, StorageOperationStatus> updateAttributeValueInResourceInstance(ComponentInstanceProperty attribute, String resourceInstanceId, boolean inTransaction);
 
 
-	public Either<ComponentInstanceInput, StorageOperationStatus> addInputValueToResourceInstance(ComponentInstanceInput input, String resourceInstanceId, Integer innerElement, boolean b);
+    public Either<ComponentInstanceInput, StorageOperationStatus> addInputValueToResourceInstance(ComponentInstanceInput input, String resourceInstanceId, Integer innerElement, boolean b);
 
-	public Either<ComponentInstanceInput, StorageOperationStatus> updateInputValueInResourceInstance(ComponentInstanceInput input, String resourceInstanceId, boolean b);
+    public Either<ComponentInstanceInput, StorageOperationStatus> updateInputValueInResourceInstance(ComponentInstanceInput input, String resourceInstanceId, boolean b);
 
 
-	public StorageOperationStatus updateCustomizationUUID(String componentInstanceId);
-	/**
-	 * updates componentInstance modificationTime on graph node
-	 * @param componentInstance
-	 * @param componentInstanceType
-	 * @param modificationTime
-	 * @param inTransaction
-	 * @return
-	 */
-	public Either<ComponentInstanceData, StorageOperationStatus> updateComponentInstanceModificationTimeAndCustomizationUuidOnGraph(ComponentInstance componentInstance, NodeTypeEnum componentInstanceType, Long modificationTime, boolean inTransaction);
+    public StorageOperationStatus updateCustomizationUUID(String componentInstanceId);
+    /**
+     * updates componentInstance modificationTime on graph node
+     * @param componentInstance
+     * @param componentInstanceType
+     * @param modificationTime
+     * @param inTransaction
+     * @return
+     */
+    public Either<ComponentInstanceData, StorageOperationStatus> updateComponentInstanceModificationTimeAndCustomizationUuidOnGraph(ComponentInstance componentInstance, NodeTypeEnum componentInstanceType, Long modificationTime, boolean inTransaction);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.java
index c9e6d69..55c38d0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.java
@@ -20,87 +20,86 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.List;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.resources.data.ConsumerData;
 
-import fj.data.Either;
+import java.util.List;
 
 public interface IConsumerOperation {
 
-	/**
-	 * the method updates the node in the graph with the given ConsumerData
-	 * 
-	 * @param consumerData
-	 *            the object we want to store
-	 * @param inTransaction
-	 *            inTransaction is the operation part of a transaction, in case the value is false the action will be committed in the end of the method
-	 * @return the updated object returned from the graph
-	 */
-	Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData, boolean inTransaction);
-
-	/**
-	 * the method updates the node in the graph with the given ConsumerData
-	 * 
-	 * @param consumerData
-	 *            the object we want to store
-	 * @return the updated object returned from the graph
-	 */
-	Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData);
-
-	/**
-	 * the method deletes the node with the given unique id
-	 * 
-	 * @param consumerName
-	 *            the unique id by witch we will look up the credential we want to delete
-	 * @param inTransaction
-	 *            inTransaction is the operation part of a transaction, in case the value is false the action will be committed in the end of the method
-	 * @return the deleted object returned from the graph
-	 */
-	Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName, boolean inTransaction);
-
-	/**
-	 * the method deletes the node with the given unique id
-	 * 
-	 * @param consumerName
-	 *            the unique id by witch we will look up the credential we want to delete
-	 * @return the deleted object returned from the graph
-	 */
-	Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName);
-
-	/**
-	 * the method creates a new nod in the grape representing the supplied credential object
-	 * 
-	 * @param consumerData
-	 *            the object we want to store
-	 * @param inTransaction
-	 *            is the operation part of a transaction, in case the value is false the action will be committed in the end of the method
-	 * @return the newly stored object returned from the graph
-	 */
-	Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData, boolean inTransaction);
-
-	/**
-	 * the method creates a new nod in the grape representing the supplied credential object
-	 * 
-	 * @param consumerData
-	 *            the object we want to store
-	 * @return the newly stored object returned from the graph
-	 */
-	Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData);
-
-	/**
-	 * the method retrieves the credential for the given consumer name
-	 * 
-	 * @param consumerName
-	 *            the unique id by witch we will look up the credential
-	 * @return ConsumerData or the error received during the operation
-	 */
-	Either<ConsumerData, StorageOperationStatus> getCredentials(String consumerName);
-
-	/**
-	 *
-	 * @return all consumers
+    /**
+     * the method updates the node in the graph with the given ConsumerData
+     *
+     * @param consumerData
+     *            the object we want to store
+     * @param inTransaction
+     *            inTransaction is the operation part of a transaction, in case the value is false the action will be committed in the end of the method
+     * @return the updated object returned from the graph
      */
-	Either<List<ConsumerData>, StorageOperationStatus> getAll();
+    Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData, boolean inTransaction);
+
+    /**
+     * the method updates the node in the graph with the given ConsumerData
+     *
+     * @param consumerData
+     *            the object we want to store
+     * @return the updated object returned from the graph
+     */
+    Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData);
+
+    /**
+     * the method deletes the node with the given unique id
+     *
+     * @param consumerName
+     *            the unique id by witch we will look up the credential we want to delete
+     * @param inTransaction
+     *            inTransaction is the operation part of a transaction, in case the value is false the action will be committed in the end of the method
+     * @return the deleted object returned from the graph
+     */
+    Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName, boolean inTransaction);
+
+    /**
+     * the method deletes the node with the given unique id
+     *
+     * @param consumerName
+     *            the unique id by witch we will look up the credential we want to delete
+     * @return the deleted object returned from the graph
+     */
+    Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName);
+
+    /**
+     * the method creates a new nod in the grape representing the supplied credential object
+     *
+     * @param consumerData
+     *            the object we want to store
+     * @param inTransaction
+     *            is the operation part of a transaction, in case the value is false the action will be committed in the end of the method
+     * @return the newly stored object returned from the graph
+     */
+    Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData, boolean inTransaction);
+
+    /**
+     * the method creates a new nod in the grape representing the supplied credential object
+     *
+     * @param consumerData
+     *            the object we want to store
+     * @return the newly stored object returned from the graph
+     */
+    Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData);
+
+    /**
+     * the method retrieves the credential for the given consumer name
+     *
+     * @param consumerName
+     *            the unique id by witch we will look up the credential
+     * @return ConsumerData or the error received during the operation
+     */
+    Either<ConsumerData, StorageOperationStatus> getCredentials(String consumerName);
+
+    /**
+     *
+     * @return all consumers
+     */
+    Either<List<ConsumerData>, StorageOperationStatus> getAll();
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.java
index 9377abb..1851771 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.java
@@ -20,26 +20,25 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
 import fj.data.Either;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
 
 public interface IDataTypeOperation {
 
-	/**
-	 * @param dataTypeDefinition
-	 * @return
-	 */
-	public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition);
+    /**
+     * @param dataTypeDefinition
+     * @return
+     */
+    public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition);
 
-	public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition, boolean inTransaction);
+    public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition, boolean inTransaction);
 
-	/**
-	 * @param name
-	 * @return
-	 */
-	public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name);
+    /**
+     * @param name
+     * @return
+     */
+    public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name);
 
-	public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction);
+    public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java
index 0a82be8..71a54a3 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java
@@ -20,9 +20,7 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.List;
-import java.util.Map;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
@@ -34,61 +32,62 @@
 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
 import org.openecomp.sdc.be.resources.data.CategoryData;
 
-import fj.data.Either;
+import java.util.List;
+import java.util.Map;
 
 public interface IElementOperation {
 
-	Either<List<CategoryDefinition>, ActionStatus> getAllResourceCategories();
+    Either<List<CategoryDefinition>, ActionStatus> getAllResourceCategories();
 
-	Either<List<CategoryDefinition>, ActionStatus> getAllServiceCategories();
+    Either<List<CategoryDefinition>, ActionStatus> getAllServiceCategories();
 
-	Either<List<CategoryDefinition>, ActionStatus> getAllProductCategories();
+    Either<List<CategoryDefinition>, ActionStatus> getAllProductCategories();
 
-	public Either<List<Tag>, ActionStatus> getAllTags();
+    public Either<List<Tag>, ActionStatus> getAllTags();
 
-	public Either<List<PropertyScope>, ActionStatus> getAllPropertyScopes();
+    public Either<List<PropertyScope>, ActionStatus> getAllPropertyScopes();
 
-	public Either<List<ArtifactType>, ActionStatus> getAllArtifactTypes();
+    public Either<List<ArtifactType>, ActionStatus> getAllArtifactTypes();
 
-	public Either<Map<String, Object>, ActionStatus> getAllDeploymentArtifactTypes();
+    public Either<Map<String, Object>, ActionStatus> getAllDeploymentArtifactTypes();
 
-	public Either<Integer, ActionStatus> getDefaultHeatTimeout();
+    public Either<Integer, ActionStatus> getDefaultHeatTimeout();
 
-	public <T extends GraphNode> Either<CategoryData, StorageOperationStatus> getCategoryData(String name, NodeTypeEnum type, Class<T> clazz);
+    public <T extends GraphNode> Either<CategoryData, StorageOperationStatus> getCategoryData(String name, NodeTypeEnum type, Class<T> clazz);
 
-	public <T extends GraphNode> Either<org.openecomp.sdc.be.resources.data.category.CategoryData, StorageOperationStatus> getNewCategoryData(String name, NodeTypeEnum type, Class<T> clazz);
+    public <T extends GraphNode> Either<org.openecomp.sdc.be.resources.data.category.CategoryData, StorageOperationStatus> getNewCategoryData(String name, NodeTypeEnum type, Class<T> clazz);
 
-	public Either<Map<String, String>, ActionStatus> getResourceTypesMap();
+    public Either<Map<String, String>, ActionStatus> getResourceTypesMap();
 
-	Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType);
+    Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType);
 
-	Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType, boolean inTransaction);
+    Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType, boolean inTransaction);
 
-	Either<CategoryDefinition, ActionStatus> deleteCategory(NodeTypeEnum nodeType, String categoryId);
+    Either<CategoryDefinition, ActionStatus> deleteCategory(NodeTypeEnum nodeType, String categoryId);
 
-	Either<SubCategoryDefinition, ActionStatus> deleteSubCategory(NodeTypeEnum nodeType, String subCategoryId);
+    Either<SubCategoryDefinition, ActionStatus> deleteSubCategory(NodeTypeEnum nodeType, String subCategoryId);
 
-	Either<Boolean, ActionStatus> isCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName);
+    Either<Boolean, ActionStatus> isCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName);
 
-	Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, NodeTypeEnum nodeType);
+    Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, NodeTypeEnum nodeType);
 
-	Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, NodeTypeEnum nodeType, boolean inTransaction);
+    Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, NodeTypeEnum nodeType, boolean inTransaction);
 
-	Either<List<CategoryDefinition>, ActionStatus> getAllCategories(NodeTypeEnum nodeType, boolean inTransaction);
+    Either<List<CategoryDefinition>, ActionStatus> getAllCategories(NodeTypeEnum nodeType, boolean inTransaction);
 
-	Either<CategoryDefinition, ActionStatus> getCategory(NodeTypeEnum nodeType, String categoryId);
+    Either<CategoryDefinition, ActionStatus> getCategory(NodeTypeEnum nodeType, String categoryId);
 
-	Either<SubCategoryDefinition, ActionStatus> getSubCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName);
+    Either<SubCategoryDefinition, ActionStatus> getSubCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName);
 
-	Either<Boolean, ActionStatus> isSubCategoryUniqueForCategory(NodeTypeEnum nodeType, String subCategoryNormName, String parentCategoryId);
+    Either<Boolean, ActionStatus> isSubCategoryUniqueForCategory(NodeTypeEnum nodeType, String subCategoryNormName, String parentCategoryId);
 
-	Either<GroupingDefinition, ActionStatus> createGrouping(String subCategoryId, GroupingDefinition grouping, NodeTypeEnum nodeType);
+    Either<GroupingDefinition, ActionStatus> createGrouping(String subCategoryId, GroupingDefinition grouping, NodeTypeEnum nodeType);
 
-	Either<GroupingDefinition, ActionStatus> deleteGrouping(NodeTypeEnum nodeType, String groupingId);
+    Either<GroupingDefinition, ActionStatus> deleteGrouping(NodeTypeEnum nodeType, String groupingId);
 
-	Either<SubCategoryDefinition, ActionStatus> getSubCategory(NodeTypeEnum nodeType, String subCategoryId);
+    Either<SubCategoryDefinition, ActionStatus> getSubCategory(NodeTypeEnum nodeType, String subCategoryId);
 
-	Either<Boolean, ActionStatus> isGroupingUniqueForSubCategory(NodeTypeEnum nodeType, String groupingNormName, String parentSubCategoryId);
+    Either<Boolean, ActionStatus> isGroupingUniqueForSubCategory(NodeTypeEnum nodeType, String groupingNormName, String parentSubCategoryId);
 
-	Either<GroupingDefinition, ActionStatus> getGroupingUniqueForType(NodeTypeEnum nodeType, String groupingNormalizedName);
+    Either<GroupingDefinition, ActionStatus> getGroupingUniqueForType(NodeTypeEnum nodeType, String groupingNormalizedName);
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java
index 29da562..8642ec8 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java
@@ -24,12 +24,12 @@
 
 public interface IGraphLockOperation {
 
-	public abstract StorageOperationStatus lockComponent(String componentId, NodeTypeEnum nodeType);
+    StorageOperationStatus lockComponent(String componentId, NodeTypeEnum nodeType);
 
-	public abstract StorageOperationStatus unlockComponent(String componentId, NodeTypeEnum nodeType);
+    StorageOperationStatus unlockComponent(String componentId, NodeTypeEnum nodeType);
 
-	public abstract StorageOperationStatus lockComponentByName(String name, NodeTypeEnum nodeType);
+    StorageOperationStatus lockComponentByName(String name, NodeTypeEnum nodeType);
 
-	public abstract StorageOperationStatus unlockComponentByName(String name, String componentId, NodeTypeEnum nodeType);
+    StorageOperationStatus unlockComponentByName(String name, String componentId, NodeTypeEnum nodeType);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupInstanceOperation.java
index 6fe56d0..86be01d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupInstanceOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupInstanceOperation.java
@@ -21,26 +21,25 @@
 package org.openecomp.sdc.be.model.operations.api;
 
 
-import java.util.List;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.model.GroupInstance;
 import org.openecomp.sdc.be.resources.data.ArtifactData;
 
-import fj.data.Either;
+import java.util.List;
 
 public interface IGroupInstanceOperation {
-	
 
-	public Either<List<GroupInstance>, StorageOperationStatus> getAllGroupInstances(String componentInstId, NodeTypeEnum compInstNodeType);
 
-	public Either<Integer, StorageOperationStatus> increaseAndGetGroupInstancePropertyCounter(String groupInstanceId);
+    public Either<List<GroupInstance>, StorageOperationStatus> getAllGroupInstances(String componentInstId, NodeTypeEnum compInstNodeType);
 
-	public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToGroupInstance(ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, boolean inTransaction);
+    public Either<Integer, StorageOperationStatus> increaseAndGetGroupInstancePropertyCounter(String groupInstanceId);
 
-	public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInGroupInstance(ComponentInstanceProperty gropuInstanceProperty, String groupInstanceId, boolean inTransaction);
+    public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToGroupInstance(ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, boolean inTransaction);
 
-	StorageOperationStatus dissociateAndAssociateGroupsInstanceFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact);
+    public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInGroupInstance(ComponentInstanceProperty gropuInstanceProperty, String groupInstanceId, boolean inTransaction);
+
+    StorageOperationStatus dissociateAndAssociateGroupsInstanceFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java
index 0695346..182adc8 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java
@@ -20,23 +20,21 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.List;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
-import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.GroupProperty;
 import org.openecomp.sdc.be.resources.data.ArtifactData;
 
-import fj.data.Either;
+import java.util.List;
 
 public interface IGroupOperation {
 
-	public Either<List<GraphRelation>, TitanOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, String artifactId);
+    public Either<List<GraphRelation>, StorageOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, String artifactId);
 
-	public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact, boolean inTransaction);
+    public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact, boolean inTransaction);
 
-	public boolean isGroupExist(String groupName, boolean inTransaction);
+    public boolean isGroupExist(String groupName, boolean inTransaction);
 
-	public StorageOperationStatus validateAndUpdatePropertyValue(GroupProperty property);
+    public StorageOperationStatus validateAndUpdatePropertyValue(GroupProperty property);
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.java
index 0fe50ff..a82bfc8 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.java
@@ -20,42 +20,26 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.model.GroupTypeDefinition;
-import org.openecomp.sdc.be.resources.data.GroupTypeData;
-
 import fj.data.Either;
+import org.openecomp.sdc.be.model.GroupTypeDefinition;
 
 public interface IGroupTypeOperation {
 
-	/**
-	 * @param groupTypeDefinition
-	 * @return
-	 */
-	public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition);
+    Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition);
 
-	public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition, boolean inTransaction);
-	
-	public Either<GroupTypeDefinition, StorageOperationStatus> upgradeGroupType(GroupTypeDefinition groupTypeDefinitionNew, GroupTypeDefinition groupTypeDefinitionOld);
+    Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition, boolean inTransaction);
 
-    public Either<GroupTypeDefinition, StorageOperationStatus> upgradeGroupType(GroupTypeDefinition groupTypeDefinitionNew, GroupTypeDefinition groupTypeDefinitionOld, boolean inTransaction);
+    Either<GroupTypeDefinition, StorageOperationStatus> updateGroupType(GroupTypeDefinition updatedGroupType, GroupTypeDefinition currGroupType);
 
-	/**
-	 * @param uniqueId
-	 * @return
-	 */
-	public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId);
+    Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId, boolean inTransaction);
 
-	public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId, boolean inTransaction);
+    Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String name);
 
-	public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String name);
+    Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String name, boolean inTransaction);
 
-	public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String name, boolean inTransaction);
+    Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String name, String version);
 
-	public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String name, String version);
+    Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String name, String version, boolean inTransaction);
 
-	public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String name, String version, boolean inTransaction);
-
-	public Either<GroupTypeData, TitanOperationStatus> getLatestGroupTypeByNameFromGraph(String name);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.java
index f903b4f..8e573f6 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.java
@@ -20,27 +20,26 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.List;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.HeatParameterDefinition;
 import org.openecomp.sdc.be.resources.data.HeatParameterValueData;
 
-import fj.data.Either;
+import java.util.List;
 
 public interface IHeatParametersOperation {
 
-	public StorageOperationStatus addPropertiesToGraph(List<HeatParameterDefinition> properties, String resourceId, NodeTypeEnum nodeType);
+    public StorageOperationStatus addPropertiesToGraph(List<HeatParameterDefinition> properties, String resourceId, NodeTypeEnum nodeType);
 
-	public StorageOperationStatus getHeatParametersOfNode(NodeTypeEnum nodeType, String uniqueId, List<HeatParameterDefinition> properties);
+    public StorageOperationStatus getHeatParametersOfNode(NodeTypeEnum nodeType, String uniqueId, List<HeatParameterDefinition> properties);
 
-	public Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteAllHeatParametersAssociatedToNode(NodeTypeEnum nodeType, String uniqueId);
+    public Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteAllHeatParametersAssociatedToNode(NodeTypeEnum nodeType, String uniqueId);
 
-	public StorageOperationStatus deleteAllHeatValuesAssociatedToNode(NodeTypeEnum parentNodeType, String parentUniqueId);
+    public StorageOperationStatus deleteAllHeatValuesAssociatedToNode(NodeTypeEnum parentNodeType, String parentUniqueId);
 
-	public StorageOperationStatus validateAndUpdateProperty(HeatParameterDefinition heatParam);
+    public StorageOperationStatus validateAndUpdateProperty(HeatParameterDefinition heatParam);
 
-	public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel);
+    public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel);
 
-	public StorageOperationStatus updateHeatParameters(List<HeatParameterDefinition> properties);
+    public StorageOperationStatus updateHeatParameters(List<HeatParameterDefinition> properties);
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.java
index 54405cf..0c03ee3 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.java
@@ -27,8 +27,8 @@
 
 public interface IInputsOperation {
 
-	ImmutablePair<TitanOperationStatus, String> findInputValue(String resourceInstanceId, String propertyId);
+    ImmutablePair<TitanOperationStatus, String> findInputValue(String resourceInstanceId, String propertyId);
 
-	ComponentInstanceInput buildResourceInstanceInput(InputValueData propertyValueData, ComponentInstanceInput resourceInstanceInput);
+    ComponentInstanceInput buildResourceInstanceInput(InputValueData propertyValueData, ComponentInstanceInput resourceInstanceInput);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.java
index ca29ab0..fd9addd 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.java
@@ -20,35 +20,34 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.Map;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.Operation;
 
-import fj.data.Either;
+import java.util.Map;
 
 public interface IInterfaceLifecycleOperation {
 
-	public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceOnResource(InterfaceDefinition interf, String resourceId, String interfaceName, boolean failIfExist, boolean inTransaction);
+    public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceOnResource(InterfaceDefinition interf, String resourceId, String interfaceName, boolean failIfExist, boolean inTransaction);
 
-	public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToResource(InterfaceDefinition interf, String resourceId, String interfaceName, boolean inTransaction);
+    public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToResource(InterfaceDefinition interf, String resourceId, String interfaceName, boolean inTransaction);
 
-	public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, String operationName, Operation interf);
+    public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, String operationName, Operation interf);
 
-	public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, String operationName, Operation interf, boolean inTransaction);
+    public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, String operationName, Operation interf, boolean inTransaction);
 
-	public Either<Operation, StorageOperationStatus> deleteInterfaceOperation(String resourceId, String interfaceName, String operationName, boolean inTransaction);
+    public Either<Operation, StorageOperationStatus> deleteInterfaceOperation(String resourceId, String interfaceName, String operationName, boolean inTransaction);
 
-	public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource(String resourceId, boolean recursively, boolean inTransaction);
+    public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource(String resourceId, boolean recursively, boolean inTransaction);
 
-	public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource(String resourceId, boolean recursively);
+    public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource(String resourceId, boolean recursively);
 
-	public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf);
+    public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf);
 
-	public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf, boolean inTransaction);
+    public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf, boolean inTransaction);
 
-	public Either<InterfaceDefinition, StorageOperationStatus> getInterface(String interfaceId);
+    public Either<InterfaceDefinition, StorageOperationStatus> getInterface(String interfaceId);
 
-	public String getShortInterfaceName(InterfaceDataDefinition interfaceDefinition);
+    public String getShortInterfaceName(InterfaceDataDefinition interfaceDefinition);
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.java
index 46a6aef..3c0b85d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.java
@@ -20,12 +20,11 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.List;
-import java.util.Set;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
 
-import fj.data.Either;
+import java.util.List;
+import java.util.Set;
 
 public interface IPolicyTypeOperation {
 
@@ -35,6 +34,6 @@
 
     Either<PolicyTypeDefinition, StorageOperationStatus> updatePolicyType(PolicyTypeDefinition updatedPolicyType, PolicyTypeDefinition currPolicyType);
 
-    Either<List<PolicyTypeDefinition>, StorageOperationStatus> getAllPolicyTypes(Set<String> excludedPolicyTypes);
+    List<PolicyTypeDefinition> getAllPolicyTypes(Set<String> excludedPolicyTypes);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java
index c3218e6..effd195 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java
@@ -20,59 +20,58 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.Map;
-
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.be.model.IComplexDefaultValue;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 
-import fj.data.Either;
+import java.util.Map;
 
 public interface IPropertyOperation {
 
-	/**
-	 * Delete all properties of resource
-	 * 
-	 * @param nodeType
-	 * @param uniqueId
-	 * @return
-	 */
-	public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deleteAllPropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId);
+    /**
+     * Delete all properties of resource
+     *
+     * @param nodeType
+     * @param uniqueId
+     * @return
+     */
+    public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deleteAllPropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId);
 
-	/**
-	 * same as deleteAllPropertiesAssociatedToNode but returns empty map if node has no properties
-	 * @param nodeType
-	 * @param uniqueId
-	 * @return
-	 */
-	Either<Map<String, PropertyDefinition>, StorageOperationStatus> deletePropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId);
+    /**
+     * same as deleteAllPropertiesAssociatedToNode but returns empty map if node has no properties
+     * @param nodeType
+     * @param uniqueId
+     * @return
+     */
+    Either<Map<String, PropertyDefinition>, StorageOperationStatus> deletePropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId);
 
-	public boolean isPropertyDefaultValueValid(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes);
+    public boolean isPropertyDefaultValueValid(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes);
 
-	public boolean isPropertyTypeValid(IComplexDefaultValue propertyDefinition);
+    public boolean isPropertyTypeValid(IComplexDefaultValue propertyDefinition);
 
-	public ImmutablePair<String, Boolean> isPropertyInnerTypeValid(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes);
+    public ImmutablePair<String, Boolean> isPropertyInnerTypeValid(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes);
 
-	/**
-	 * @param dataTypeDefinition
-	 * @return
-	 */
-	public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition);
+    /**
+     * @param dataTypeDefinition
+     * @return
+     */
+    public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition);
 
-	/**
-	 * @param name
-	 * @return
-	 */
-	public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name);
+    /**
+     * @param name
+     * @return
+     */
+    public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name);
 
-	public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction);
+    public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction);
 
-	public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name);
+    public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name);
 
-	public StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes);
+    public StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes);
 
-	public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition);
+    public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.java
index 6f33643..196661f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.java
@@ -20,29 +20,28 @@
 
 package org.openecomp.sdc.be.model.operations.api;
 
-import java.util.List;
-import java.util.Map;
-
+import fj.data.Either;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.model.User;
 
-import fj.data.Either;
+import java.util.List;
+import java.util.Map;
 
 public interface IUserAdminOperation {
 
-	public Either<User, ActionStatus> getUserData(String id, boolean inTransaction);
+    public Either<User, ActionStatus> getUserData(String id, boolean inTransaction);
 
-	public Either<User, StorageOperationStatus> saveUserData(User user);
+    public Either<User, StorageOperationStatus> saveUserData(User user);
 
-	public Either<User, StorageOperationStatus> updateUserData(User user);
+    public Either<User, StorageOperationStatus> updateUserData(User user);
 
-	public Either<User, StorageOperationStatus> deActivateUser(User user);
+    public Either<User, StorageOperationStatus> deActivateUser(User user);
 
-	public Either<User, ActionStatus> deleteUserData(String id);
+    public Either<User, ActionStatus> deleteUserData(String id);
 
-	public Either<List<User>, ActionStatus> getAllUsersWithRole(String role, String status);
+    public Either<List<User>, ActionStatus> getAllUsersWithRole(String role, String status);
 
-	public Either<List<Edge>, StorageOperationStatus> getUserPendingTasksList(User user, Map<String, Object> properties);
+    public Either<List<Edge>, StorageOperationStatus> getUserPendingTasksList(User user, Map<String, Object> properties);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.java
index c2346a3..ca700b0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.java
@@ -22,6 +22,46 @@
 
 public enum StorageOperationStatus {
 
-	OK, CONNECTION_FAILURE, BAD_REQUEST, ENTITY_ALREADY_EXISTS, GRAPH_IS_LOCK, GENERAL_ERROR, USER_NOT_FOUND, PERMISSION_ERROR, HTTP_PROTOCOL_ERROR, STORAGE_NOT_AVAILABLE, READ_ONLY_STORAGE, STORAGE_LEGACY_INDEX_ERROR, SCHEMA_ERROR, TRANSACTION_ERROR, EXEUCTION_FAILED, NOT_FOUND, OPERATION_NOT_SUPPORTED, CATEGORY_NOT_FOUND, PARENT_RESOURCE_NOT_FOUND, MULTIPLE_PARENT_RESOURCE_FOUND, INCONSISTENCY, GRAPH_IS_NOT_AVAILABLE, SCHEMA_VIOLATION, FAILED_TO_LOCK_ELEMENT, INVALID_ID, MATCH_NOT_FOUND, ARTIFACT_NOT_FOUND, DISTR_ENVIRONMENT_NOT_AVAILABLE, DISTR_ENVIRONMENT_NOT_FOUND, DISTR_ENVIRONMENT_SENT_IS_INVALID, DISTR_ARTIFACT_NOT_FOUND, OVERLOAD, INVALID_TYPE, INVALID_VALUE, INVALID_INNER_TYPE, CSAR_NOT_FOUND, GROUP_INVALID_CONTENT, CANNOT_UPDATE_EXISTING_ENTITY, PROPERTY_NAME_ALREADY_EXISTS, INVALID_PROPERTY,;
+    OK, 
+    CONNECTION_FAILURE, 
+    BAD_REQUEST, 
+    ENTITY_ALREADY_EXISTS, 
+    GRAPH_IS_LOCK, 
+    GENERAL_ERROR, 
+    USER_NOT_FOUND, 
+    PERMISSION_ERROR, 
+    HTTP_PROTOCOL_ERROR, 
+    STORAGE_NOT_AVAILABLE, 
+    READ_ONLY_STORAGE, 
+    STORAGE_LEGACY_INDEX_ERROR, 
+    SCHEMA_ERROR, 
+    TRANSACTION_ERROR, 
+    EXEUCTION_FAILED, 
+    NOT_FOUND, 
+    OPERATION_NOT_SUPPORTED, 
+    CATEGORY_NOT_FOUND, 
+    PARENT_RESOURCE_NOT_FOUND, 
+    MULTIPLE_PARENT_RESOURCE_FOUND, 
+    INCONSISTENCY, 
+    GRAPH_IS_NOT_AVAILABLE, 
+    SCHEMA_VIOLATION, 
+    FAILED_TO_LOCK_ELEMENT, 
+    INVALID_ID, 
+    MATCH_NOT_FOUND, 
+    ARTIFACT_NOT_FOUND, 
+    DISTR_ENVIRONMENT_NOT_AVAILABLE, 
+    DISTR_ENVIRONMENT_NOT_FOUND, 
+    DISTR_ENVIRONMENT_SENT_IS_INVALID, 
+    DISTR_ARTIFACT_NOT_FOUND, 
+    OVERLOAD, 
+    INVALID_TYPE, 
+    INVALID_VALUE, 
+    INVALID_INNER_TYPE, 
+    CSAR_NOT_FOUND, 
+    GROUP_INVALID_CONTENT, 
+    CANNOT_UPDATE_EXISTING_ENTITY, 
+    PROPERTY_NAME_ALREADY_EXISTS, 
+    INVALID_PROPERTY,
+    COMPONENT_IS_ARCHIVED;
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/TypeOperations.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/TypeOperations.java
new file mode 100644
index 0000000..d858153
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/TypeOperations.java
@@ -0,0 +1,24 @@
+package org.openecomp.sdc.be.model.operations.api;
+
+import fj.data.Either;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
+
+import javax.validation.constraints.NotNull;
+
+public interface TypeOperations<T extends ToscaDataDefinition> {
+
+    T addType(T newTypeDefinition);
+
+    T getType(String uniqueId);
+
+    T getLatestType(String uniqueId);
+
+    boolean isSameType(@NotNull T type1,@NotNull T type2);
+
+    T updateType(T currentTypeDefinition, T newTypeDefinition);
+    
+    static <T> Either<T, StorageOperationStatus> mapOkStatus(StorageOperationStatus status, T obj) {
+        return status != StorageOperationStatus.OK? Either.right(status) : Either.left(obj);
+    }
+
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java
index f0e4056..b42581a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java
@@ -20,13 +20,12 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.lang.reflect.Type;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+import com.google.gson.reflect.TypeToken;
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
@@ -51,331 +50,303 @@
 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
 import org.openecomp.sdc.be.resources.data.UniqueIdData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
 
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonElement;
-import com.google.gson.reflect.TypeToken;
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
 
 public abstract class AbstractOperation {
-	private static Logger log = LoggerFactory.getLogger(AbstractOperation.class.getName());
-	@javax.annotation.Resource
-	protected TitanGenericDao titanGenericDao;
-	public static final String EMPTY_VALUE = null;
 
-	protected Gson gson = new Gson();
+    private static final Logger log = Logger.getLogger(AbstractOperation.class.getName());
 
-	@javax.annotation.Resource
-	protected ApplicationDataTypeCache applicationDataTypeCache;
+    @Autowired
+    protected TitanGenericDao titanGenericDao;
 
-	protected DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
+    public static final String EMPTY_VALUE = null;
 
-	protected <SomeData extends GraphNode, SomeDefenition> Either<SomeData, TitanOperationStatus> addDefinitionToNodeType(SomeDefenition someDefinition, NodeTypeEnum nodeType, String nodeUniqueId, final GraphEdgeLabels edgeType,
-			Supplier<SomeData> dataBuilder, Supplier<String> defNameGenerator) {
-		String defName = defNameGenerator.get();
-		log.debug("Got {} {}", defName, someDefinition);
+    protected Gson gson = new Gson();
 
-		SomeData someData = dataBuilder.get();
+    @Autowired
+    protected ApplicationDataTypeCache applicationDataTypeCache;
 
-		log.debug("Before adding {} to graph. data = {}", defName, someData);
+    protected DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
 
-		@SuppressWarnings("unchecked")
-		Either<SomeData, TitanOperationStatus> eitherSomeData = titanGenericDao.createNode(someData, (Class<SomeData>) someData.getClass());
+    protected <SomeData extends GraphNode, SomeDefenition> Either<SomeData, TitanOperationStatus> addDefinitionToNodeType(SomeDefenition someDefinition, NodeTypeEnum nodeType, String nodeUniqueId, final GraphEdgeLabels edgeType,
+            Supplier<SomeData> dataBuilder, Supplier<String> defNameGenerator) {
+        String defName = defNameGenerator.get();
+        log.debug("Got {} {}", defName, someDefinition);
 
-		log.debug("After adding {} to graph. status is = {}", defName, eitherSomeData);
+        SomeData someData = dataBuilder.get();
 
-		if (eitherSomeData.isRight()) {
-			TitanOperationStatus operationStatus = eitherSomeData.right().value();
-			log.error("Failed to add {}  to graph. status is {}", defName, operationStatus);
-			return Either.right(operationStatus);
-		}
-		UniqueIdData uniqueIdData = new UniqueIdData(nodeType, nodeUniqueId);
-		log.debug("Before associating {} to {}.", uniqueIdData, defName);
+        log.debug("Before adding {} to graph. data = {}", defName, someData);
 
-		Either<GraphRelation, TitanOperationStatus> eitherRelations = titanGenericDao.createRelation(uniqueIdData, eitherSomeData.left().value(), edgeType, null);
-		if (eitherRelations.isRight()) {
-			TitanOperationStatus operationStatus = eitherRelations.right().value();
-			BeEcompErrorManager.getInstance().logInternalFlowError("AddDefinitionToNodeType", "Failed to associate" + nodeType.getName() + " " + nodeUniqueId + "to " + defName + "in graph. status is " + operationStatus, ErrorSeverity.ERROR);
-			return Either.right(operationStatus);
-		}
-		return Either.left(eitherSomeData.left().value());
-	}
+        @SuppressWarnings("unchecked")
+        Either<SomeData, TitanOperationStatus> eitherSomeData = titanGenericDao.createNode(someData, (Class<SomeData>) someData.getClass());
 
-	protected <SomeData extends GraphNode, SomeDefenition> TitanOperationStatus addDefinitionToNodeType(TitanVertex vertex, SomeDefenition someDefinition, NodeTypeEnum nodeType, String nodeUniqueId, final GraphEdgeLabels edgeType,
-			Supplier<SomeData> dataBuilder, Supplier<String> defNameGenerator) {
-		String defName = defNameGenerator.get();
-		log.debug("Got {} {}", defName, someDefinition);
+        log.debug("After adding {} to graph. status is = {}", defName, eitherSomeData);
 
-		SomeData someData = dataBuilder.get();
+        if (eitherSomeData.isRight()) {
+            TitanOperationStatus operationStatus = eitherSomeData.right().value();
+            log.error("Failed to add {}  to graph. status is {}", defName, operationStatus);
+            return Either.right(operationStatus);
+        }
+        UniqueIdData uniqueIdData = new UniqueIdData(nodeType, nodeUniqueId);
+        log.debug("Before associating {} to {}.", uniqueIdData, defName);
 
-		log.debug("Before adding {} to graph. data = {}", defName, someData);
+        Either<GraphRelation, TitanOperationStatus> eitherRelations = titanGenericDao.createRelation(uniqueIdData, eitherSomeData.left().value(), edgeType, null);
+        if (eitherRelations.isRight()) {
+            TitanOperationStatus operationStatus = eitherRelations.right().value();
+            BeEcompErrorManager.getInstance().logInternalFlowError("AddDefinitionToNodeType", "Failed to associate" + nodeType.getName() + " " + nodeUniqueId + "to " + defName + "in graph. status is " + operationStatus, ErrorSeverity.ERROR);
+            return Either.right(operationStatus);
+        }
+        return Either.left(eitherSomeData.left().value());
+    }
 
-		@SuppressWarnings("unchecked")
-		Either<TitanVertex, TitanOperationStatus> eitherSomeData = titanGenericDao.createNode(someData);
+    protected <SomeData extends GraphNode, SomeDefenition> TitanOperationStatus addDefinitionToNodeType(TitanVertex vertex, SomeDefenition someDefinition, NodeTypeEnum nodeType, String nodeUniqueId, final GraphEdgeLabels edgeType,
+            Supplier<SomeData> dataBuilder, Supplier<String> defNameGenerator) {
+        String defName = defNameGenerator.get();
+        log.debug("Got {} {}", defName, someDefinition);
 
-		log.debug("After adding {} to graph. status is = {}", defName, eitherSomeData);
+        SomeData someData = dataBuilder.get();
 
-		if (eitherSomeData.isRight()) {
-			TitanOperationStatus operationStatus = eitherSomeData.right().value();
-			log.error("Failed to add {}  to graph. status is {}", defName, operationStatus);
-			return operationStatus;
-		}
+        log.debug("Before adding {} to graph. data = {}", defName, someData);
 
-		TitanOperationStatus relations = titanGenericDao.createEdge(vertex, eitherSomeData.left().value(), edgeType, null);
-		if (!relations.equals(TitanOperationStatus.OK)) {
-			TitanOperationStatus operationStatus = relations;
-			BeEcompErrorManager.getInstance().logInternalFlowError("AddDefinitionToNodeType", "Failed to associate" + nodeType.getName() + " " + nodeUniqueId + "to " + defName + "in graph. status is " + operationStatus, ErrorSeverity.ERROR);
-			return operationStatus;
-		}
-		return relations;
-	}
+        @SuppressWarnings("unchecked")
+        Either<TitanVertex, TitanOperationStatus> eitherSomeData = titanGenericDao.createNode(someData);
 
-	interface NodeElementFetcher<ElementDefinition> {
-		TitanOperationStatus findAllNodeElements(String nodeId, List<ElementDefinition> listTofill);
-	}
+        log.debug("After adding {} to graph. status is = {}", defName, eitherSomeData);
 
-	public <ElementDefinition> TitanOperationStatus findAllResourceElementsDefinitionRecursively(String resourceId, List<ElementDefinition> elements, NodeElementFetcher<ElementDefinition> singleNodeFetcher) {
+        if (eitherSomeData.isRight()) {
+            TitanOperationStatus operationStatus = eitherSomeData.right().value();
+            log.error("Failed to add {}  to graph. status is {}", defName, operationStatus);
+            return operationStatus;
+        }
 
-		if (log.isTraceEnabled())
-			log.trace("Going to fetch elements under resource {}", resourceId);
-		TitanOperationStatus resourceAttributesStatus = singleNodeFetcher.findAllNodeElements(resourceId, elements);
+        TitanOperationStatus relations = titanGenericDao.createEdge(vertex, eitherSomeData.left().value(), edgeType, null);
+        if (!relations.equals(TitanOperationStatus.OK)) {
+            BeEcompErrorManager.getInstance().logInternalFlowError("AddDefinitionToNodeType", "Failed to associate" + nodeType.getName() + " " + nodeUniqueId + "to " + defName + "in graph. status is " + relations, ErrorSeverity.ERROR);
+            return relations;
+        }
+        return relations;
+    }
 
-		if (resourceAttributesStatus != TitanOperationStatus.OK) {
-			return resourceAttributesStatus;
-		}
+    interface NodeElementFetcher<ElementDefinition> {
+        TitanOperationStatus findAllNodeElements(String nodeId, List<ElementDefinition> listTofill);
+    }
 
-		Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
-				ResourceMetadataData.class);
+    public <ElementDefinition> TitanOperationStatus findAllResourceElementsDefinitionRecursively(String resourceId, List<ElementDefinition> elements, NodeElementFetcher<ElementDefinition> singleNodeFetcher) {
 
-		if (parentNodes.isRight()) {
-			TitanOperationStatus parentNodesStatus = parentNodes.right().value();
-			if (parentNodesStatus != TitanOperationStatus.NOT_FOUND) {
-				BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find parent elements of resource " + resourceId + ". status is " + parentNodesStatus, ErrorSeverity.ERROR);
-				return parentNodesStatus;
-			}
-		}
+        if (log.isTraceEnabled())
+            log.trace("Going to fetch elements under resource {}", resourceId);
+        TitanOperationStatus resourceAttributesStatus = singleNodeFetcher.findAllNodeElements(resourceId, elements);
 
-		if (parentNodes.isLeft()) {
-			ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
-			String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
-			TitanOperationStatus addParentIntStatus = findAllResourceElementsDefinitionRecursively(parentUniqueId, elements, singleNodeFetcher);
+        if (resourceAttributesStatus != TitanOperationStatus.OK) {
+            return resourceAttributesStatus;
+        }
 
-			if (addParentIntStatus != TitanOperationStatus.OK) {
-				BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find all resource elements of resource " + parentUniqueId, ErrorSeverity.ERROR);
+        Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
+                ResourceMetadataData.class);
 
-				return addParentIntStatus;
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+        if (parentNodes.isRight()) {
+            TitanOperationStatus parentNodesStatus = parentNodes.right().value();
+            if (parentNodesStatus != TitanOperationStatus.NOT_FOUND) {
+                BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find parent elements of resource " + resourceId + ". status is " + parentNodesStatus, ErrorSeverity.ERROR);
+                return parentNodesStatus;
+            }
+        }
 
-	protected <T, TStatus> void handleTransactionCommitRollback(boolean inTransaction, Either<T, TStatus> result) {
-		if (!inTransaction) {
-			if (result == null || result.isRight()) {
-				log.error("Going to execute rollback on graph.");
-				titanGenericDao.rollback();
-			} else {
-				log.debug("Going to execute commit on graph.");
-				titanGenericDao.commit();
-			}
-		}
-	}
+        if (parentNodes.isLeft()) {
+            ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
+            String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
+            TitanOperationStatus addParentIntStatus = findAllResourceElementsDefinitionRecursively(parentUniqueId, elements, singleNodeFetcher);
 
-	public <ElementTypeDefinition> Either<ElementTypeDefinition, StorageOperationStatus> getElementType(Function<String, Either<ElementTypeDefinition, TitanOperationStatus>> elementGetter, String uniqueId, boolean inTransaction) {
-		Either<ElementTypeDefinition, StorageOperationStatus> result = null;
-		try {
+            if (addParentIntStatus != TitanOperationStatus.OK) {
+                BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find all resource elements of resource " + parentUniqueId, ErrorSeverity.ERROR);
 
-			Either<ElementTypeDefinition, TitanOperationStatus> ctResult = elementGetter.apply(uniqueId);
+                return addParentIntStatus;
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-			if (ctResult.isRight()) {
-				TitanOperationStatus status = ctResult.right().value();
-				if (status != TitanOperationStatus.NOT_FOUND) {
-					log.error("Failed to retrieve information on element uniqueId: {}. status is {}", uniqueId, status);
-				}
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
-				return result;
-			}
+    protected <T, TStatus> void handleTransactionCommitRollback(boolean inTransaction, Either<T, TStatus> result) {
+        if (!inTransaction) {
+            if (result == null || result.isRight()) {
+                log.error("Going to execute rollback on graph.");
+                titanGenericDao.rollback();
+            } else {
+                log.debug("Going to execute commit on graph.");
+                titanGenericDao.commit();
+            }
+        }
+    }
 
-			result = Either.left(ctResult.left().value());
 
-			return result;
-		} finally {
-			handleTransactionCommitRollback(inTransaction, result);
+    /**
+     * @param propertyDefinition
+     * @return
+     */
 
-		}
+    protected StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
 
-	}
+        log.trace("Going to validate property type and value. {}", propertyDefinition);
 
-	/**
-	 * @param propertyDefinition
-	 * @return
-	 */
+        String propertyType = propertyDefinition.getType();
+        String value = propertyDefinition.getDefaultValue();
 
-	protected StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
+        ToscaPropertyType type = getType(propertyType);
 
-		log.trace("Going to validate property type and value. {}", propertyDefinition);
+        if (type == null) {
 
-		String propertyType = propertyDefinition.getType();
-		String value = propertyDefinition.getDefaultValue();
-
-		ToscaPropertyType type = getType(propertyType);
-
-		if (type == null) {
-
-			DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
-			if (dataTypeDefinition == null) {
-				log.debug("The type {}  of property cannot be found.", propertyType);
-				return StorageOperationStatus.INVALID_TYPE;
-			}
-
-			StorageOperationStatus status = validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes);
-
-			return status;
+            DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
+            if (dataTypeDefinition == null) {
+                log.debug("The type {}  of property cannot be found.", propertyType);
+                return StorageOperationStatus.INVALID_TYPE;
+            }
 
-		}
-		String innerType = null;
+            return validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes);
 
-		Either<String, TitanOperationStatus> checkInnerType = getInnerType(type, () -> propertyDefinition.getSchema());
-		if (checkInnerType.isRight()) {
-			return StorageOperationStatus.INVALID_TYPE;
-		}
-		innerType = checkInnerType.left().value();
+        }
+        String innerType = null;
 
-		log.trace("After validating property type {}", propertyType);
+        Either<String, TitanOperationStatus> checkInnerType = getInnerType(type, propertyDefinition::getSchema);
+        if (checkInnerType.isRight()) {
+            return StorageOperationStatus.INVALID_TYPE;
+        }
+        innerType = checkInnerType.left().value();
 
-		boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
-		if (false == isValidProperty) {
-			log.info("The value {} of property from type {} is invalid", value, type);
-			return StorageOperationStatus.INVALID_VALUE;
-		}
+        log.trace("After validating property type {}", propertyType);
 
-		PropertyValueConverter converter = type.getConverter();
+        boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
+        if (!isValidProperty) {
+            log.info("The value {} of property from type {} is invalid", value, type);
+            return StorageOperationStatus.INVALID_VALUE;
+        }
 
-		if (isEmptyValue(value)) {
-			log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE);
-			propertyDefinition.setDefaultValue(EMPTY_VALUE);
-		} else if (false == isEmptyValue(value)) {
-			String convertedValue = converter.convert(value, innerType, dataTypes);
-			propertyDefinition.setDefaultValue(convertedValue);
-		}
-		return StorageOperationStatus.OK;
-	}
+        PropertyValueConverter converter = type.getConverter();
 
-	protected ToscaPropertyType getType(String propertyType) {
+        if (isEmptyValue(value)) {
+            log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE);
+            propertyDefinition.setDefaultValue(EMPTY_VALUE);
+        } else if (!isEmptyValue(value)) {
+            String convertedValue = converter.convert(value, innerType, dataTypes);
+            propertyDefinition.setDefaultValue(convertedValue);
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
+    protected ToscaPropertyType getType(String propertyType) {
 
-		return type;
+        return ToscaPropertyType.isValidType(propertyType);
 
-	}
+    }
 
-	protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		if (isEmptyValue(value)) {
-			return true;
-		}
+    protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        if (isEmptyValue(value)) {
+            return true;
+        }
 
-		PropertyTypeValidator validator = type.getValidator();
+        PropertyTypeValidator validator = type.getValidator();
 
-		return validator.isValid(value, innerType, dataTypes);
-	}
+        return validator.isValid(value, innerType, dataTypes);
+    }
 
-	public boolean isEmptyValue(String value) {
-		return value == null;
-	}
+    public boolean isEmptyValue(String value) {
+        return value == null;
+    }
 
-	public boolean isNullParam(String value) {
-		return value == null;
-	}
+    public boolean isNullParam(String value) {
+        return value == null;
+    }
 
-	protected StorageOperationStatus validateAndUpdateComplexValue(IComplexDefaultValue propertyDefinition, String propertyType,
+    protected StorageOperationStatus validateAndUpdateComplexValue(IComplexDefaultValue propertyDefinition, String propertyType,
 
-			String value, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> dataTypes) {
+            String value, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> dataTypes) {
 
-		ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
+        ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
 
-		if (validateResult.right.booleanValue() == false) {
-			log.debug("The value {} of property from type {} is invalid", propertyType, propertyType);
-			return StorageOperationStatus.INVALID_VALUE;
-		}
+        if (!validateResult.right.booleanValue()) {
+            log.debug("The value {} of property from type {} is invalid", propertyType, propertyType);
+            return StorageOperationStatus.INVALID_VALUE;
+        }
 
-		JsonElement jsonElement = validateResult.left;
+        JsonElement jsonElement = validateResult.left;
 
-		log.trace("Going to update value in property definition {} {}" , propertyDefinition.getName() , (jsonElement != null ? jsonElement.toString() : null));
+        log.trace("Going to update value in property definition {} {}" , propertyDefinition.getName() , (jsonElement != null ? jsonElement.toString() : null));
 
-		updateValue(propertyDefinition, jsonElement);
+        updateValue(propertyDefinition, jsonElement);
 
-		return StorageOperationStatus.OK;
-	}
+        return StorageOperationStatus.OK;
+    }
 
-	protected void updateValue(IComplexDefaultValue propertyDefinition, JsonElement jsonElement) {
+    protected void updateValue(IComplexDefaultValue propertyDefinition, JsonElement jsonElement) {
 
-		propertyDefinition.setDefaultValue(getValueFromJsonElement(jsonElement));
+        propertyDefinition.setDefaultValue(getValueFromJsonElement(jsonElement));
 
-	}
+    }
 
-	protected String getValueFromJsonElement(JsonElement jsonElement) {
-		String value = null;
+    protected String getValueFromJsonElement(JsonElement jsonElement) {
+        String value = null;
 
-		if (jsonElement == null || jsonElement.isJsonNull()) {
-			value = EMPTY_VALUE;
-		} else {
-			value = jsonElement.toString();
-		}
+        if (jsonElement == null || jsonElement.isJsonNull()) {
+            value = EMPTY_VALUE;
+        } else {
+            value = jsonElement.toString();
+        }
 
-		return value; 
-	}
+        return value;
+    }
 
-	protected Either<String, TitanOperationStatus> getInnerType(ToscaPropertyType type, Supplier<SchemaDefinition> schemeGen) {
-		String innerType = null;
-		if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
+    protected Either<String, TitanOperationStatus> getInnerType(ToscaPropertyType type, Supplier<SchemaDefinition> schemeGen) {
+        String innerType = null;
+        if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
 
-			SchemaDefinition def = schemeGen.get();// propDataDef.getSchema();
-			if (def == null) {
-				log.debug("Schema doesn't exists for property of type {}", type);
-				return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-			}
-			PropertyDataDefinition propDef = def.getProperty();
-			if (propDef == null) {
-				log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
-				return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-			}
-			innerType = propDef.getType();
-		}
-		return Either.left(innerType);
-	}
+            SchemaDefinition def = schemeGen.get();
+            if (def == null) {
+                log.debug("Schema doesn't exists for property of type {}", type);
+                return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+            }
+            PropertyDataDefinition propDef = def.getProperty();
+            if (propDef == null) {
+                log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
+                return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+            }
+            innerType = propDef.getType();
+        }
+        return Either.left(innerType);
+    }
 
-	/**
-	 * Convert Constarint object to json in order to add it to the Graph
-	 * 
-	 * @param constraints
-	 * @return
-	 */
-	public List<String> convertConstraintsToString(List<PropertyConstraint> constraints) {
+    /**
+     * Convert Constarint object to json in order to add it to the Graph
+     *
+     * @param constraints
+     * @return
+     */
+    public List<String> convertConstraintsToString(List<PropertyConstraint> constraints) {
 
-		if (constraints == null || constraints.isEmpty()) {
-			return null;
-		}
+        if (constraints == null || constraints.isEmpty()) {
+            return null;
+        }
 
-		return constraints.stream().map(gson::toJson).collect(Collectors.toList());
-	}
+        return constraints.stream().map(gson::toJson).collect(Collectors.toList());
+    }
 
-	public List<PropertyConstraint> convertConstraints(List<String> constraints) {
+    public List<PropertyConstraint> convertConstraints(List<String> constraints) {
 
-		if (constraints == null || constraints.isEmpty()) {
-			return null;
-		}
+        if (constraints == null || constraints.isEmpty()) {
+            return null;
+        }
 
-		Type constraintType = new TypeToken<PropertyConstraint>() {
-		}.getType();
+        Type constraintType = new TypeToken<PropertyConstraint>() {
+        }.getType();
 
-		Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create();
+        Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create();
 
-		return constraints.stream().map(c -> gson.fromJson(c, PropertyConstraint.class)).collect(Collectors.toList());
-	}
+        return constraints.stream().map(c -> gson.fromJson(c, PropertyConstraint.class)).collect(Collectors.toList());
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java
index 8f34b32..349ee28 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java
@@ -20,12 +20,8 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
@@ -47,775 +43,776 @@
 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
 import org.openecomp.sdc.be.resources.data.ServiceMetadataData;
 import org.openecomp.sdc.be.resources.data.UniqueIdData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 
 @Component("additional-information-operation")
 public class AdditionalInformationOperation implements IAdditionalInformationOperation {
 
+    private static final String GOING_TO_EXECUTE_COMMIT_ON_GRAPH = "Going to execute commit on graph.";
+	private static final String GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH = "Going to execute rollback on graph.";
+	private static final String ADDITIONAL_INFORMATION_OF = "additional information of ";
 	public static final String EMPTY_VALUE = null;
 
-	public AdditionalInformationOperation() {
-		super();
-	}
+    public AdditionalInformationOperation() {
+        super();
+    }
 
-	private static Logger log = LoggerFactory.getLogger(AdditionalInformationOperation.class.getName());
+    private static final Logger log = Logger.getLogger(AdditionalInformationOperation.class.getName());
 
-	@javax.annotation.Resource
-	private TitanGenericDao titanGenericDao;
+    @javax.annotation.Resource
+    private TitanGenericDao titanGenericDao;
 
-	@Override
-	public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String key, String value) {
+    @Override
+    public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String key, String value) {
 
-		TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
-		if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
-			return Either.right(verifyNodeTypeVsComponent);
-		}
+        TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
+        if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
+            return Either.right(verifyNodeTypeVsComponent);
+        }
 
-		Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
-				NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
+        Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
+                NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
 
-		if (getResult.isRight()) {
-			TitanOperationStatus status = getResult.right().value();
-			return Either.right(status);
-		}
+        if (getResult.isRight()) {
+            TitanOperationStatus status = getResult.right().value();
+            return Either.right(status);
+        }
 
-		ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
-		AdditionalInfoParameterData parameterData = immutablePair.getLeft();
-		Map<String, String> parameters = parameterData.getParameters();
-		if (parameters == null) {
-			parameters = new HashMap<String, String>();
-			parameterData.setParameters(parameters);
-		}
-		Map<String, String> idToKey = parameterData.getIdToKey();
-		if (idToKey == null) {
-			idToKey = new HashMap<String, String>();
-			parameterData.setIdToKey(idToKey);
-		}
+        ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
+        AdditionalInfoParameterData parameterData = immutablePair.getLeft();
+        Map<String, String> parameters = parameterData.getParameters();
+        if (parameters == null) {
+            parameters = new HashMap<>();
+            parameterData.setParameters(parameters);
+        }
+        Map<String, String> idToKey = parameterData.getIdToKey();
+        if (idToKey == null) {
+            idToKey = new HashMap<>();
+            parameterData.setIdToKey(idToKey);
+        }
 
-		Integer lastCreatedCounter = parameterData.getAdditionalInfoParameterDataDefinition().getLastCreatedCounter();
-		lastCreatedCounter++;
+        Integer lastCreatedCounter = parameterData.getAdditionalInfoParameterDataDefinition().getLastCreatedCounter();
+        lastCreatedCounter++;
 
-		if (parameters.containsKey(key)) {
-			log.debug("The key {} already exists under component {}", key, componentId);
-			return Either.right(TitanOperationStatus.ALREADY_EXIST);
-		}
+        if (parameters.containsKey(key)) {
+            log.debug("The key {} already exists under component {}", key, componentId);
+            return Either.right(TitanOperationStatus.ALREADY_EXIST);
+        }
 
-		idToKey.put(String.valueOf(lastCreatedCounter), key);
-		parameters.put(key, value);
-		parameterData.getAdditionalInfoParameterDataDefinition().setLastCreatedCounter(lastCreatedCounter);
+        idToKey.put(String.valueOf(lastCreatedCounter), key);
+        parameters.put(key, value);
+        parameterData.getAdditionalInfoParameterDataDefinition().setLastCreatedCounter(lastCreatedCounter);
 
-		Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
+        Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
 
-		if (updateNode.isRight()) {
-			TitanOperationStatus status = updateNode.right().value();
-			BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("UpdateAdditionalInformationParameter", "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status));
-			return Either.right(status);
-		}
+        if (updateNode.isRight()) {
+            TitanOperationStatus status = updateNode.right().value();
+            BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("UpdateAdditionalInformationParameter", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + componentId, String.valueOf(status));
+            return Either.right(status);
+        }
 
-		AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, updateNode.left().value());
+        AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, updateNode.left().value());
 
-		return Either.left(informationDefinition);
+        return Either.left(informationDefinition);
 
-	}
+    }
 
-	@Override
-	public Either<AdditionalInformationDefinition, TitanOperationStatus> updateAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String id, String key, String value) {
+    @Override
+    public Either<AdditionalInformationDefinition, TitanOperationStatus> updateAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String id, String key, String value) {
 
-		TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
-		if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
-			return Either.right(verifyNodeTypeVsComponent);
-		}
+        TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
+        if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
+            return Either.right(verifyNodeTypeVsComponent);
+        }
 
-		Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
-				NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
+        Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
+                NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
 
-		if (getResult.isRight()) {
-			TitanOperationStatus status = getResult.right().value();
-			return Either.right(status);
-		}
+        if (getResult.isRight()) {
+            TitanOperationStatus status = getResult.right().value();
+            return Either.right(status);
+        }
 
-		ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
-		AdditionalInfoParameterData parameterData = immutablePair.getLeft();
-		Map<String, String> parameters = parameterData.getParameters();
-		Map<String, String> idToKey = parameterData.getIdToKey();
-		if (idToKey == null || false == idToKey.containsKey(id)) {
-			return Either.right(TitanOperationStatus.INVALID_ID);
-		}
+        ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
+        AdditionalInfoParameterData parameterData = immutablePair.getLeft();
+        Map<String, String> parameters = parameterData.getParameters();
+        Map<String, String> idToKey = parameterData.getIdToKey();
+        if (idToKey == null || !idToKey.containsKey(id)) {
+            return Either.right(TitanOperationStatus.INVALID_ID);
+        }
 
-		String origKey = idToKey.get(id);
+        String origKey = idToKey.get(id);
 
-		if (false == origKey.equals(key)) {
-			if (parameters.containsKey(key)) {
-				log.debug("The key {} already exists", key);
-				return Either.right(TitanOperationStatus.ALREADY_EXIST);
-			}
-			String removed = parameters.remove(origKey);
-			log.trace("The key-value {} = {} was removed from additionalInformation", origKey, removed);
-		}
-		parameters.put(key, value);
-		idToKey.put(id, key);
+        if (!origKey.equals(key)) {
+            if (parameters.containsKey(key)) {
+                log.debug("The key {} already exists", key);
+                return Either.right(TitanOperationStatus.ALREADY_EXIST);
+            }
+            String removed = parameters.remove(origKey);
+            log.trace("The key-value {} = {} was removed from additionalInformation", origKey, removed);
+        }
+        parameters.put(key, value);
+        idToKey.put(id, key);
 
-		Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
+        Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
 
-		if (updateNode.isRight()) {
-			TitanOperationStatus status = updateNode.right().value();
-			BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("UpdateAdditionalInformationParameter", "additional information of resource " + componentId, String.valueOf(status));
-			return Either.right(status);
-		}
+        if (updateNode.isRight()) {
+            TitanOperationStatus status = updateNode.right().value();
+            BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("UpdateAdditionalInformationParameter", "additional information of resource " + componentId, String.valueOf(status));
+            return Either.right(status);
+        }
 
-		AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, updateNode.left().value());
+        AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, updateNode.left().value());
 
-		return Either.left(informationDefinition);
+        return Either.left(informationDefinition);
 
-	}
+    }
 
-	@Override
-	public Either<AdditionalInformationDefinition, TitanOperationStatus> deleteAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String id) {
+    @Override
+    public Either<AdditionalInformationDefinition, TitanOperationStatus> deleteAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String id) {
 
-		TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
-		if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
-			return Either.right(verifyNodeTypeVsComponent);
-		}
+        TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
+        if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
+            return Either.right(verifyNodeTypeVsComponent);
+        }
 
-		Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
-				NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
+        Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
+                NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
 
-		if (getResult.isRight()) {
-			TitanOperationStatus status = getResult.right().value();
-			return Either.right(status);
-		}
+        if (getResult.isRight()) {
+            TitanOperationStatus status = getResult.right().value();
+            return Either.right(status);
+        }
 
-		ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
-		AdditionalInfoParameterData parameterData = immutablePair.getLeft();
-		Map<String, String> parameters = parameterData.getParameters();
-		Map<String, String> idToKey = parameterData.getIdToKey();
+        ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
+        AdditionalInfoParameterData parameterData = immutablePair.getLeft();
+        Map<String, String> parameters = parameterData.getParameters();
+        Map<String, String> idToKey = parameterData.getIdToKey();
 
-		if (idToKey == null || false == idToKey.containsKey(id)) {
-			return Either.right(TitanOperationStatus.INVALID_ID);
-		}
+        if (idToKey == null || !idToKey.containsKey(id)) {
+            return Either.right(TitanOperationStatus.INVALID_ID);
+        }
 
-		String key = idToKey.get(id);
-		String removedKey = idToKey.remove(id);
-		String removedValue = parameters.remove(key);
-		log.trace("The key-value {} = {} was removed from additionalInformation", removedKey, removedValue);
+        String key = idToKey.get(id);
+        String removedKey = idToKey.remove(id);
+        String removedValue = parameters.remove(key);
+        log.trace("The key-value {} = {} was removed from additionalInformation", removedKey, removedValue);
 
-		Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
+        Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
 
-		if (updateNode.isRight()) {
-			TitanOperationStatus status = updateNode.right().value();
-			BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("DeleteAdditionalInformationParameter", "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status));
-			return Either.right(status);
-		}
+        if (updateNode.isRight()) {
+            TitanOperationStatus status = updateNode.right().value();
+            BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("DeleteAdditionalInformationParameter", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + componentId, String.valueOf(status));
+            return Either.right(status);
+        }
 
-		AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, updateNode.left().value());
+        AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, updateNode.left().value());
 
-		return Either.left(informationDefinition);
+        return Either.left(informationDefinition);
 
-	}
+    }
 
-	private AdditionalInformationDefinition createInformationDefinitionFromNode(String resourceId, Map<String, String> parameters, Map<String, String> idToKey, AdditionalInfoParameterData additionalInfoParameterData) {
-		AdditionalInfoParameterDataDefinition dataDefinition = additionalInfoParameterData.getAdditionalInfoParameterDataDefinition();
+    private AdditionalInformationDefinition createInformationDefinitionFromNode(String resourceId, Map<String, String> parameters, Map<String, String> idToKey, AdditionalInfoParameterData additionalInfoParameterData) {
+        AdditionalInfoParameterDataDefinition dataDefinition = additionalInfoParameterData.getAdditionalInfoParameterDataDefinition();
 
-		AdditionalInformationDefinition informationDefinition = new AdditionalInformationDefinition(dataDefinition, resourceId, convertParameters(parameters, idToKey));
-		return informationDefinition;
-	}
+        return new AdditionalInformationDefinition(dataDefinition, resourceId, convertParameters(parameters, idToKey));
+    }
 
-	private List<AdditionalInfoParameterInfo> convertParameters(Map<String, String> parameters, Map<String, String> idToKey) {
+    private List<AdditionalInfoParameterInfo> convertParameters(Map<String, String> parameters, Map<String, String> idToKey) {
 
-		List<AdditionalInfoParameterInfo> list = new ArrayList<AdditionalInfoParameterInfo>();
+        List<AdditionalInfoParameterInfo> list = new ArrayList<>();
 
-		if (parameters != null) {
-			for (Entry<String, String> idToKeyEntry : idToKey.entrySet()) {
+        if (parameters != null) {
+            for (Entry<String, String> idToKeyEntry : idToKey.entrySet()) {
 
-				String id = idToKeyEntry.getKey();
-				String key = idToKeyEntry.getValue();
+                String id = idToKeyEntry.getKey();
+                String key = idToKeyEntry.getValue();
 
-				String value = parameters.get(key);
+                String value = parameters.get(key);
 
-				AdditionalInfoParameterInfo parameterInfo = new AdditionalInfoParameterInfo(id, key, value);
-				list.add(parameterInfo);
-			}
+                AdditionalInfoParameterInfo parameterInfo = new AdditionalInfoParameterInfo(id, key, value);
+                list.add(parameterInfo);
+            }
 
-		}
+        }
 
-		return list;
-	}
+        return list;
+    }
 
-	@Override
-	public Either<AdditionalInfoParameterData, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId) {
+    @Override
+    public Either<AdditionalInfoParameterData, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId) {
 
-		UniqueIdData from = new UniqueIdData(nodeType, componentId);
+        UniqueIdData from = new UniqueIdData(nodeType, componentId);
 
-		String uniqueId = UniqueIdBuilder.buildAdditionalInformationUniqueId(componentId);
-		AdditionalInfoParameterDataDefinition additionalInfoParameterDataDefinition = new AdditionalInfoParameterDataDefinition();
-		additionalInfoParameterDataDefinition.setUniqueId(uniqueId);
+        String uniqueId = UniqueIdBuilder.buildAdditionalInformationUniqueId(componentId);
+        AdditionalInfoParameterDataDefinition additionalInfoParameterDataDefinition = new AdditionalInfoParameterDataDefinition();
+        additionalInfoParameterDataDefinition.setUniqueId(uniqueId);
 
-		AdditionalInfoParameterData additionalInfoParameterData = new AdditionalInfoParameterData(additionalInfoParameterDataDefinition, new HashMap<String, String>(), new HashMap<String, String>());
+        AdditionalInfoParameterData additionalInfoParameterData = new AdditionalInfoParameterData(additionalInfoParameterDataDefinition, new HashMap<>(), new HashMap<>());
 
-		Either<AdditionalInfoParameterData, TitanOperationStatus> createNode = titanGenericDao.createNode(additionalInfoParameterData, AdditionalInfoParameterData.class);
-		if (createNode.isRight()) {
-			TitanOperationStatus status = createNode.right().value();
-			BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("AddAdditionalInformationNode", uniqueId, String.valueOf(status));
-			return Either.right(status);
-		}
+        Either<AdditionalInfoParameterData, TitanOperationStatus> createNode = titanGenericDao.createNode(additionalInfoParameterData, AdditionalInfoParameterData.class);
+        if (createNode.isRight()) {
+            TitanOperationStatus status = createNode.right().value();
+            BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("AddAdditionalInformationNode", uniqueId, String.valueOf(status));
+            return Either.right(status);
+        }
 
-		AdditionalInfoParameterData to = createNode.left().value();
+        AdditionalInfoParameterData to = createNode.left().value();
 
-		Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, GraphEdgeLabels.ADDITIONAL_INFORMATION, null);
-		if (createRelation.isRight()) {
-			TitanOperationStatus status = createRelation.right().value();
-			return Either.right(status);
-		}
+        Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, GraphEdgeLabels.ADDITIONAL_INFORMATION, null);
+        if (createRelation.isRight()) {
+            TitanOperationStatus status = createRelation.right().value();
+            return Either.right(status);
+        }
 
-		return Either.left(to);
-	}
+        return Either.left(to);
+    }
 
-	@Override
-	public Either<TitanVertex, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, TitanVertex metadataVertex) {
+    @Override
+    public Either<TitanVertex, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, TitanVertex metadataVertex) {
 
-		String uniqueId = UniqueIdBuilder.buildAdditionalInformationUniqueId(componentId);
-		AdditionalInfoParameterDataDefinition additionalInfoParameterDataDefinition = new AdditionalInfoParameterDataDefinition();
-		additionalInfoParameterDataDefinition.setUniqueId(uniqueId);
+        String uniqueId = UniqueIdBuilder.buildAdditionalInformationUniqueId(componentId);
+        AdditionalInfoParameterDataDefinition additionalInfoParameterDataDefinition = new AdditionalInfoParameterDataDefinition();
+        additionalInfoParameterDataDefinition.setUniqueId(uniqueId);
 
-		AdditionalInfoParameterData additionalInfoParameterData = new AdditionalInfoParameterData(additionalInfoParameterDataDefinition, new HashMap<String, String>(), new HashMap<String, String>());
+        AdditionalInfoParameterData additionalInfoParameterData = new AdditionalInfoParameterData(additionalInfoParameterDataDefinition, new HashMap<>(), new HashMap<>());
 
-		Either<TitanVertex, TitanOperationStatus> createNode = titanGenericDao.createNode(additionalInfoParameterData);
-		if (createNode.isRight()) {
-			TitanOperationStatus status = createNode.right().value();
-			BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("AddAdditionalInformationNode", uniqueId, String.valueOf(status));
-			return Either.right(status);
-		}
+        Either<TitanVertex, TitanOperationStatus> createNode = titanGenericDao.createNode(additionalInfoParameterData);
+        if (createNode.isRight()) {
+            TitanOperationStatus status = createNode.right().value();
+            BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("AddAdditionalInformationNode", uniqueId, String.valueOf(status));
+            return Either.right(status);
+        }
 
-		TitanVertex additionalInfoVertex = createNode.left().value();
+        TitanVertex additionalInfoVertex = createNode.left().value();
 
-		TitanOperationStatus createRelation = titanGenericDao.createEdge(metadataVertex, additionalInfoVertex, GraphEdgeLabels.ADDITIONAL_INFORMATION, null);
+        TitanOperationStatus createRelation = titanGenericDao.createEdge(metadataVertex, additionalInfoVertex, GraphEdgeLabels.ADDITIONAL_INFORMATION, null);
 
-		if (!createRelation.equals(TitanOperationStatus.OK)) {
-			return Either.right(createRelation);
-		}
-		return Either.left(additionalInfoVertex);
-	}
+        if (!createRelation.equals(TitanOperationStatus.OK)) {
+            return Either.right(createRelation);
+        }
+        return Either.left(additionalInfoVertex);
+    }
 
-	public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters) {
+    public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters) {
 
-		Either<AdditionalInfoParameterData, TitanOperationStatus> status = this.addAdditionalInformationNode(nodeType, componentId);
+        Either<AdditionalInfoParameterData, TitanOperationStatus> status = this.addAdditionalInformationNode(nodeType, componentId);
 
-		if (status.isRight()) {
-			return Either.right(status.right().value());
-		}
+        if (status.isRight()) {
+            return Either.right(status.right().value());
+        }
 
-		AdditionalInfoParameterData parameterData = status.left().value();
+        AdditionalInfoParameterData parameterData = status.left().value();
 
-		populateParameterNodeWithParameters(parameterData, parameters);
+        populateParameterNodeWithParameters(parameterData, parameters);
 
-		Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
+        Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
 
-		if (updateNode.isRight()) {
-			return Either.right(updateNode.right().value());
-		}
+        if (updateNode.isRight()) {
+            return Either.right(updateNode.right().value());
+        }
 
-		AdditionalInformationDefinition informationDefinition = convertAdditionalInformationDataToDefinition(updateNode.left().value(), componentId);
+        AdditionalInformationDefinition informationDefinition = convertAdditionalInformationDataToDefinition(updateNode.left().value(), componentId);
 
-		return Either.left(informationDefinition);
-	}
+        return Either.left(informationDefinition);
+    }
 
-	public TitanOperationStatus addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters, TitanVertex metadataVertex) {
+    public TitanOperationStatus addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters, TitanVertex metadataVertex) {
 
-		Either<TitanVertex, TitanOperationStatus> status = this.addAdditionalInformationNode(nodeType, componentId, metadataVertex);
+        Either<TitanVertex, TitanOperationStatus> status = this.addAdditionalInformationNode(nodeType, componentId, metadataVertex);
 
-		if (status.isRight()) {
-			return status.right().value();
-		}
-		TitanVertex additionalInfoVertex = status.left().value();
+        if (status.isRight()) {
+            return status.right().value();
+        }
+        TitanVertex additionalInfoVertex = status.left().value();
 
-		Map<String, Object> newProp = titanGenericDao.getProperties(additionalInfoVertex);
-		AdditionalInfoParameterData parameterData = GraphElementFactory.createElement(NodeTypeEnum.AdditionalInfoParameters.getName(), GraphElementTypeEnum.Node, newProp, AdditionalInfoParameterData.class);
+        Map<String, Object> newProp = titanGenericDao.getProperties(additionalInfoVertex);
+        AdditionalInfoParameterData parameterData = GraphElementFactory.createElement(NodeTypeEnum.AdditionalInfoParameters.getName(), GraphElementTypeEnum.Node, newProp, AdditionalInfoParameterData.class);
 
-		populateParameterNodeWithParameters(parameterData, parameters);
+        populateParameterNodeWithParameters(parameterData, parameters);
 
-		TitanOperationStatus updateNode = titanGenericDao.updateVertex(parameterData, additionalInfoVertex);
+        return titanGenericDao.updateVertex(parameterData, additionalInfoVertex);
+    }
 
-		return updateNode;
-	}
+    private void populateParameterNodeWithParameters(AdditionalInfoParameterData parameterData, AdditionalInformationDefinition aiDefinition) {
 
-	private void populateParameterNodeWithParameters(AdditionalInfoParameterData parameterData, AdditionalInformationDefinition aiDefinition) {
+        if (aiDefinition != null) {
 
-		if (aiDefinition != null) {
+            Integer lastCreatedCounter = aiDefinition.getLastCreatedCounter();
+            parameterData.getAdditionalInfoParameterDataDefinition().setLastCreatedCounter(lastCreatedCounter);
+            log.trace("Set last created counter of additional information to {}", lastCreatedCounter);
 
-			Integer lastCreatedCounter = aiDefinition.getLastCreatedCounter();
-			parameterData.getAdditionalInfoParameterDataDefinition().setLastCreatedCounter(lastCreatedCounter);
-			log.trace("Set last created counter of additional information to {}", lastCreatedCounter);
+            List<AdditionalInfoParameterInfo> parameters = aiDefinition.getParameters();
+            if (parameters != null) {
 
-			List<AdditionalInfoParameterInfo> parameters = aiDefinition.getParameters();
-			if (parameters != null) {
+                Map<String, String> idToKey = new HashMap<>();
+                Map<String, String> parametersMap = new HashMap<>();
+                for (AdditionalInfoParameterInfo additionalInfoParameterInfo : parameters) {
+                    String uniqueId = additionalInfoParameterInfo.getUniqueId();
+                    String key = additionalInfoParameterInfo.getKey();
+                    String value = additionalInfoParameterInfo.getValue();
 
-				Map<String, String> idToKey = new HashMap<String, String>();
-				Map<String, String> parametersMap = new HashMap<String, String>();
-				for (AdditionalInfoParameterInfo additionalInfoParameterInfo : parameters) {
-					String uniqueId = additionalInfoParameterInfo.getUniqueId();
-					String key = additionalInfoParameterInfo.getKey();
-					String value = additionalInfoParameterInfo.getValue();
+                    if (key != null && !key.isEmpty()) {
+                        idToKey.put(uniqueId, key);
+                        parametersMap.put(key, value);
+                    }
+                }
+                parameterData.setIdToKey(idToKey);
+                parameterData.setParameters(parametersMap);
+            }
+        }
 
-					if (key != null && false == key.isEmpty()) {
-						idToKey.put(uniqueId, key);
-						parametersMap.put(key, value);
-					}
-				}
-				parameterData.setIdToKey(idToKey);
-				parameterData.setParameters(parametersMap);
-			}
-		}
+    }
 
-	}
+    @Override
+    public TitanOperationStatus findResourceAllAdditionalInformationRecursively(String uniqueId, List<AdditionalInformationDefinition> properties) {
 
-	@Override
-	public TitanOperationStatus findResourceAllAdditionalInformationRecursively(String uniqueId, List<AdditionalInformationDefinition> properties) {
+        log.trace("Going to fetch additional information under resource {}", uniqueId);
+        TitanOperationStatus resourceCapabilitiesStatus = findAdditionalInformationOfNode(NodeTypeEnum.Resource, uniqueId, properties);
 
-		log.trace("Going to fetch additional information under resource {}", uniqueId);
-		TitanOperationStatus resourceCapabilitiesStatus = findAdditionalInformationOfNode(NodeTypeEnum.Resource, uniqueId, properties);
+        if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) {
+            return resourceCapabilitiesStatus;
+        }
 
-		if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) {
-			return resourceCapabilitiesStatus;
-		}
+        Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
+                ResourceMetadataData.class);
 
-		Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
-				ResourceMetadataData.class);
+        if (parentNodes.isRight()) {
+            TitanOperationStatus parentNodesStatus = parentNodes.right().value();
+            if (!parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) {
+                log.error("Failed to find parent additional information of resource {}. status is {}", uniqueId, parentNodesStatus);
+                return parentNodesStatus;
+            }
+        }
 
-		if (parentNodes.isRight()) {
-			TitanOperationStatus parentNodesStatus = parentNodes.right().value();
-			if (false == parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) {
-				log.error("Failed to find parent additional information of resource {}. status is {}", uniqueId, parentNodesStatus);
-				return parentNodesStatus;
-			}
-		}
+        if (parentNodes.isLeft()) {
+            ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
+            String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
+            TitanOperationStatus addParentIntStatus = findResourceAllAdditionalInformationRecursively(parentUniqueId, properties);
 
-		if (parentNodes.isLeft()) {
-			ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
-			String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
-			TitanOperationStatus addParentIntStatus = findResourceAllAdditionalInformationRecursively(parentUniqueId, properties);
+            if (addParentIntStatus != TitanOperationStatus.OK) {
+                log.error("Failed to find all resource additional information of resource {}", parentUniqueId);
+                return addParentIntStatus;
+            }
+        }
+        return TitanOperationStatus.OK;
 
-			if (addParentIntStatus != TitanOperationStatus.OK) {
-				log.error("Failed to find all resource additional information of resource {}", parentUniqueId);
-				return addParentIntStatus;
-			}
-		}
-		return TitanOperationStatus.OK;
+    }
 
-	}
+    @Override
+    public TitanOperationStatus findServiceAllAdditionalInformationRecursively(String uniqueId, List<AdditionalInformationDefinition> properties) {
 
-	@Override
-	public TitanOperationStatus findServiceAllAdditionalInformationRecursively(String uniqueId, List<AdditionalInformationDefinition> properties) {
+        log.trace("Going to fetch additional information under service {}", uniqueId);
+        TitanOperationStatus resourceCapabilitiesStatus = findAdditionalInformationOfNode(NodeTypeEnum.Service, uniqueId, properties);
 
-		log.trace("Going to fetch additional information under service {}", uniqueId);
-		TitanOperationStatus resourceCapabilitiesStatus = findAdditionalInformationOfNode(NodeTypeEnum.Service, uniqueId, properties);
+        if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) {
+            return resourceCapabilitiesStatus;
+        }
 
-		if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) {
-			return resourceCapabilitiesStatus;
-		}
+        Either<ImmutablePair<ServiceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Service,
+                ServiceMetadataData.class);
 
-		Either<ImmutablePair<ServiceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Service,
-				ServiceMetadataData.class);
+        if (parentNodes.isRight()) {
+            TitanOperationStatus parentNodesStatus = parentNodes.right().value();
+            if (!parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) {
+                log.error("Failed to find parent additional information of resource {}. status is {}", uniqueId, parentNodesStatus);
+                return parentNodesStatus;
+            }
+        }
 
-		if (parentNodes.isRight()) {
-			TitanOperationStatus parentNodesStatus = parentNodes.right().value();
-			if (false == parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) {
-				log.error("Failed to find parent additional information of resource {}. status is {}", uniqueId, parentNodesStatus);
-				return parentNodesStatus;
-			}
-		}
+        if (parentNodes.isLeft()) {
+            ImmutablePair<ServiceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
+            String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
+            TitanOperationStatus addParentIntStatus = findServiceAllAdditionalInformationRecursively(parentUniqueId, properties);
 
-		if (parentNodes.isLeft()) {
-			ImmutablePair<ServiceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
-			String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
-			TitanOperationStatus addParentIntStatus = findServiceAllAdditionalInformationRecursively(parentUniqueId, properties);
+            if (addParentIntStatus != TitanOperationStatus.OK) {
+                log.error("Failed to find all resource additional information of resource {}", parentUniqueId);
+                return addParentIntStatus;
+            }
+        }
+        return TitanOperationStatus.OK;
 
-			if (addParentIntStatus != TitanOperationStatus.OK) {
-				log.error("Failed to find all resource additional information of resource {}", parentUniqueId);
-				return addParentIntStatus;
-			}
-		}
-		return TitanOperationStatus.OK;
-
-	}
+    }
 
-	private TitanOperationStatus findAdditionalInformationOfNode(NodeTypeEnum nodeType, String uniqueId, List<AdditionalInformationDefinition> properties) {
+    private TitanOperationStatus findAdditionalInformationOfNode(NodeTypeEnum nodeType, String uniqueId, List<AdditionalInformationDefinition> properties) {
 
-		Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> childNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
-				NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
+        Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> childNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
+                NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
 
-		if (childNode.isRight()) {
-			TitanOperationStatus status = childNode.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.OK;
-			}
-			return status;
-		}
+        if (childNode.isRight()) {
+            TitanOperationStatus status = childNode.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.OK;
+            }
+            return status;
+        }
 
-		ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = childNode.left().value();
-		AdditionalInfoParameterData propertyData = immutablePair.getKey();
+        ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = childNode.left().value();
+        AdditionalInfoParameterData propertyData = immutablePair.getKey();
 
-		Map<String, String> parameters = propertyData.getParameters();
-		if (parameters != null && false == parameters.isEmpty()) {
-			AdditionalInformationDefinition additionalInfoDef = this.convertAdditionalInformationDataToDefinition(propertyData, uniqueId);
-			properties.add(additionalInfoDef);
-		}
+        Map<String, String> parameters = propertyData.getParameters();
+        if (parameters != null && !parameters.isEmpty()) {
+            AdditionalInformationDefinition additionalInfoDef = this.convertAdditionalInformationDataToDefinition(propertyData, uniqueId);
+            properties.add(additionalInfoDef);
+        }
 
-		return TitanOperationStatus.OK;
+        return TitanOperationStatus.OK;
 
-	}
+    }
 
-	private AdditionalInformationDefinition convertAdditionalInformationDataToDefinition(AdditionalInfoParameterData additionalInfoData, String uniqueId) {
+    private AdditionalInformationDefinition convertAdditionalInformationDataToDefinition(AdditionalInfoParameterData additionalInfoData, String uniqueId) {
 
-		Map<String, String> parameters = additionalInfoData.getParameters();
-		Map<String, String> idToKey = additionalInfoData.getIdToKey();
+        Map<String, String> parameters = additionalInfoData.getParameters();
+        Map<String, String> idToKey = additionalInfoData.getIdToKey();
 
-		AdditionalInformationDefinition definition = new AdditionalInformationDefinition(additionalInfoData.getAdditionalInfoParameterDataDefinition(), uniqueId, convertParameters(parameters, idToKey));
-		return definition;
-	}
+        return new AdditionalInformationDefinition(additionalInfoData.getAdditionalInfoParameterDataDefinition(), uniqueId, convertParameters(parameters, idToKey));
+    }
 
-	@Override
-	public Either<AdditionalInformationDefinition, StorageOperationStatus> createAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String key, String value, boolean inTransaction) {
+    @Override
+    public Either<AdditionalInformationDefinition, StorageOperationStatus> createAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String key, String value, boolean inTransaction) {
 
-		Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
+        Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
 
-		try {
+        try {
 
-			Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.addAdditionalInformationParameter(nodeType, resourceId, key, value);
+            Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.addAdditionalInformationParameter(nodeType, resourceId, key, value);
 
-			if (either.isRight()) {
-				TitanOperationStatus status = either.right().value();
-				log.debug("Failed to add additional information property {} to component {}. Status is {}", key, resourceId, status);
-				BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("CreateAdditionalInformationParameter", "additional information of " + nodeType.getName() + " " + resourceId, String.valueOf(status));
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			} else {
-				AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
-				result = Either.left(additionalInformationDefinition);
-			}
+            if (either.isRight()) {
+                TitanOperationStatus status = either.right().value();
+                log.debug("Failed to add additional information property {} to component {}. Status is {}", key, resourceId, status);
+                BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("CreateAdditionalInformationParameter", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + resourceId, String.valueOf(status));
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            } else {
+                AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
+                result = Either.left(additionalInformationDefinition);
+            }
 
-			return result;
-		} finally {
-			commitOrRollback(inTransaction, result);
-		}
+            return result;
+        } finally {
+            commitOrRollback(inTransaction, result);
+        }
 
-	}
+    }
 
-	@Override
-	public Either<AdditionalInformationDefinition, StorageOperationStatus> updateAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, String key, String value, boolean inTransaction) {
+    @Override
+    public Either<AdditionalInformationDefinition, StorageOperationStatus> updateAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, String key, String value, boolean inTransaction) {
 
-		Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
+        Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
 
-		try {
+        try {
 
-			Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.updateAdditionalInformationParameter(nodeType, resourceId, id, key, value);
+            Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.updateAdditionalInformationParameter(nodeType, resourceId, id, key, value);
 
-			if (either.isRight()) {
-				log.info("Failed to update additional information property {} to component {}", key, resourceId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
-			} else {
-				AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
-				result = Either.left(additionalInformationDefinition);
-			}
+            if (either.isRight()) {
+                log.info("Failed to update additional information property {} to component {}", key, resourceId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
+            } else {
+                AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
+                result = Either.left(additionalInformationDefinition);
+            }
 
-			return result;
+            return result;
 
-		} finally {
-			commitOrRollback(inTransaction, result);
-		}
+        } finally {
+            commitOrRollback(inTransaction, result);
+        }
 
-	}
+    }
 
-	@Override
-	public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction) {
+    @Override
+    public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction) {
 
-		Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
+        Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
 
-		try {
+        try {
 
-			Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.deleteAdditionalInformationParameter(nodeType, resourceId, id);
+            Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.deleteAdditionalInformationParameter(nodeType, resourceId, id);
 
-			if (either.isRight()) {
-				log.error("Failed to delete additional information id {} to component {}", id, resourceId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
-			} else {
-				AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
-				result = Either.left(additionalInformationDefinition);
-			}
+            if (either.isRight()) {
+                log.error("Failed to delete additional information id {} to component {}", id, resourceId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
+            } else {
+                AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
+                result = Either.left(additionalInformationDefinition);
+            }
 
-			return result;
+            return result;
 
-		} finally {
-			commitOrRollback(inTransaction, result);
-		}
+        } finally {
+            commitOrRollback(inTransaction, result);
+        }
 
-	}
+    }
 
-	@Override
-	public Either<Integer, StorageOperationStatus> getNumberOfAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean inTransaction) {
+    @Override
+    public Either<Integer, StorageOperationStatus> getNumberOfAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean inTransaction) {
 
-		Either<Integer, StorageOperationStatus> result = null;
+        Either<Integer, StorageOperationStatus> result = null;
 
-		try {
+        try {
 
-			Either<Integer, TitanOperationStatus> either = this.getNumberOfParameters(nodeType, resourceId);
+            Either<Integer, TitanOperationStatus> either = this.getNumberOfParameters(nodeType, resourceId);
 
-			if (either.isRight()) {
-				log.error("Failed to get the number of additional information properties in component {}", resourceId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
-			} else {
-				Integer counter = either.left().value();
-				result = Either.left(counter);
-			}
+            if (either.isRight()) {
+                log.error("Failed to get the number of additional information properties in component {}", resourceId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
+            } else {
+                Integer counter = either.left().value();
+                result = Either.left(counter);
+            }
 
-			return result;
-		} finally {
-			if (false == inTransaction) {
-				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
-					titanGenericDao.rollback();
-				} else {
-					log.debug("Going to execute commit on graph.");
-					titanGenericDao.commit();
-				}
-			}
-		}
+            return result;
+        } finally {
+            if (!inTransaction) {
+                if (result == null || result.isRight()) {
+                    log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
+                    titanGenericDao.rollback();
+                } else {
+                    log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
+                    titanGenericDao.commit();
+                }
+            }
+        }
 
-	}
+    }
 
-	@Override
-	public Either<Integer, TitanOperationStatus> getNumberOfParameters(NodeTypeEnum nodeType, String resourceId) {
+    @Override
+    public Either<Integer, TitanOperationStatus> getNumberOfParameters(NodeTypeEnum nodeType, String resourceId) {
 
-		Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
-				NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
+        Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
+                NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
 
-		if (getResult.isRight()) {
-			TitanOperationStatus status = getResult.right().value();
-			return Either.right(status);
-		}
+        if (getResult.isRight()) {
+            TitanOperationStatus status = getResult.right().value();
+            return Either.right(status);
+        }
 
-		ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
-		AdditionalInfoParameterData parameterData = immutablePair.getLeft();
-		Map<String, String> parameters = parameterData.getParameters();
+        ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
+        AdditionalInfoParameterData parameterData = immutablePair.getLeft();
+        Map<String, String> parameters = parameterData.getParameters();
 
-		Integer counter = 0;
-		if (parameters != null) {
-			counter = parameters.size();
-		}
+        Integer counter = 0;
+        if (parameters != null) {
+            counter = parameters.size();
+        }
 
-		return Either.left(counter);
+        return Either.left(counter);
 
-	}
+    }
 
-	@Override
-	public Either<AdditionalInfoParameterInfo, TitanOperationStatus> getAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String id) {
+    @Override
+    public Either<AdditionalInfoParameterInfo, TitanOperationStatus> getAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String id) {
 
-		TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
-		if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
-			return Either.right(verifyNodeTypeVsComponent);
-		}
+        TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
+        if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
+            return Either.right(verifyNodeTypeVsComponent);
+        }
 
-		Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
-				NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
+        Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
+                NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
 
-		if (getResult.isRight()) {
-			TitanOperationStatus status = getResult.right().value();
-			return Either.right(status);
-		}
+        if (getResult.isRight()) {
+            TitanOperationStatus status = getResult.right().value();
+            return Either.right(status);
+        }
 
-		ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
-		AdditionalInfoParameterData parameterData = immutablePair.getLeft();
-		Map<String, String> parameters = parameterData.getParameters();
-		Map<String, String> idToKey = parameterData.getIdToKey();
+        ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
+        AdditionalInfoParameterData parameterData = immutablePair.getLeft();
+        Map<String, String> parameters = parameterData.getParameters();
+        Map<String, String> idToKey = parameterData.getIdToKey();
 
-		if (idToKey == null || false == idToKey.containsKey(id)) {
-			return Either.right(TitanOperationStatus.INVALID_ID);
-		}
+        if (idToKey == null || !idToKey.containsKey(id)) {
+            return Either.right(TitanOperationStatus.INVALID_ID);
+        }
 
-		String key = idToKey.get(id);
-		String value = parameters.get(key);
+        String key = idToKey.get(id);
+        String value = parameters.get(key);
 
-		log.trace("The key-value {} = {} was retrieved for id {}", key, value, id);
+        log.trace("The key-value {} = {} was retrieved for id {}", key, value, id);
 
-		Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
+        Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
 
-		if (updateNode.isRight()) {
-			TitanOperationStatus status = updateNode.right().value();
-			if (status != TitanOperationStatus.NOT_FOUND) {
-				BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("GetAdditionnalInformationParameter", "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status));
-			}
-			return Either.right(status);
-		}
+        if (updateNode.isRight()) {
+            TitanOperationStatus status = updateNode.right().value();
+            if (status != TitanOperationStatus.NOT_FOUND) {
+                BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("GetAdditionnalInformationParameter", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + componentId, String.valueOf(status));
+            }
+            return Either.right(status);
+        }
 
-		AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(id, key, value);
+        AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(id, key, value);
 
-		return Either.left(additionalInfoParameterInfo);
+        return Either.left(additionalInfoParameterInfo);
 
-	}
+    }
 
-	@Override
-	public Either<AdditionalInformationDefinition, TitanOperationStatus> getAllAdditionalInformationParameters(NodeTypeEnum nodeType, String componentId, boolean ignoreVerification) {
+    @Override
+    public Either<AdditionalInformationDefinition, TitanOperationStatus> getAllAdditionalInformationParameters(NodeTypeEnum nodeType, String componentId, boolean ignoreVerification) {
 
-		if (false == ignoreVerification) {
-			TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
-			if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
-				return Either.right(verifyNodeTypeVsComponent);
-			}
-		}
+        if (!ignoreVerification) {
+            TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
+            if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
+                return Either.right(verifyNodeTypeVsComponent);
+            }
+        }
 
-		Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
-				NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
+        Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
+                NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
 
-		if (getResult.isRight()) {
-			TitanOperationStatus status = getResult.right().value();
-			if (status != TitanOperationStatus.NOT_FOUND) {
-				BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("GetAdditionnalInformationParameters", "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status));
-			}
-			return Either.right(status);
-		}
+        if (getResult.isRight()) {
+            TitanOperationStatus status = getResult.right().value();
+            if (status != TitanOperationStatus.NOT_FOUND) {
+                BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("GetAdditionnalInformationParameters", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + componentId, String.valueOf(status));
+            }
+            return Either.right(status);
+        }
 
-		ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
-		AdditionalInfoParameterData parameterData = immutablePair.getLeft();
-		Map<String, String> parameters = parameterData.getParameters();
-		Map<String, String> idToKey = parameterData.getIdToKey();
+        ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
+        AdditionalInfoParameterData parameterData = immutablePair.getLeft();
+        Map<String, String> parameters = parameterData.getParameters();
+        Map<String, String> idToKey = parameterData.getIdToKey();
 
-		AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, parameterData);
+        AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, parameterData);
 
-		return Either.left(informationDefinition);
+        return Either.left(informationDefinition);
 
-	}
+    }
 
-	@Override
-	public Either<AdditionalInformationDefinition, StorageOperationStatus> getAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification, boolean inTransaction) {
+    @Override
+    public Either<AdditionalInformationDefinition, StorageOperationStatus> getAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification, boolean inTransaction) {
 
-		Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
+        Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
 
-		try {
+        try {
 
-			Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.getAllAdditionalInformationParameters(nodeType, resourceId, ignoreVerification);
+            Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.getAllAdditionalInformationParameters(nodeType, resourceId, ignoreVerification);
 
-			if (either.isRight()) {
-				TitanOperationStatus status = either.right().value();
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			} else {
-				AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
-				result = Either.left(additionalInformationDefinition);
-			}
+            if (either.isRight()) {
+                TitanOperationStatus status = either.right().value();
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            } else {
+                AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
+                result = Either.left(additionalInformationDefinition);
+            }
 
-			return result;
+            return result;
 
-		} finally {
-			commitOrRollback(inTransaction, result);
-		}
+        } finally {
+            commitOrRollback(inTransaction, result);
+        }
 
-	}
+    }
 
-	private void commitOrRollback(boolean inTransaction, Either<? extends Object, StorageOperationStatus> result) {
+    private void commitOrRollback(boolean inTransaction, Either<? extends Object, StorageOperationStatus> result) {
 
-		if (false == inTransaction) {
-			if (result == null || result.isRight()) {
-				log.error("Going to execute rollback on graph.");
-				titanGenericDao.rollback();
-			} else {
-				log.debug("Going to execute commit on graph.");
-				titanGenericDao.commit();
-			}
-		}
-	}
+        if (!inTransaction) {
+            if (result == null || result.isRight()) {
+                log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
+                titanGenericDao.rollback();
+            } else {
+                log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
+                titanGenericDao.commit();
+            }
+        }
+    }
+    
 
-	@Override
-	public Either<AdditionalInfoParameterInfo, StorageOperationStatus> getAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction) {
+    @Override
+    public Either<AdditionalInfoParameterInfo, StorageOperationStatus> getAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction) {
 
-		Either<AdditionalInfoParameterInfo, StorageOperationStatus> result = null;
+        Either<AdditionalInfoParameterInfo, StorageOperationStatus> result = null;
 
-		try {
+        try {
 
-			Either<AdditionalInfoParameterInfo, TitanOperationStatus> either = this.getAdditionalInformationParameter(nodeType, resourceId, id);
+            Either<AdditionalInfoParameterInfo, TitanOperationStatus> either = this.getAdditionalInformationParameter(nodeType, resourceId, id);
 
-			if (either.isRight()) {
-				log.error("Failed to fetch additional information property with id {} of component {}", id, resourceId);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
-			} else {
-				AdditionalInfoParameterInfo additionalInformationDefinition = either.left().value();
-				result = Either.left(additionalInformationDefinition);
-			}
+            if (either.isRight()) {
+                log.error("Failed to fetch additional information property with id {} of component {}", id, resourceId);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
+            } else {
+                AdditionalInfoParameterInfo additionalInformationDefinition = either.left().value();
+                result = Either.left(additionalInformationDefinition);
+            }
 
-			return result;
+            return result;
 
-		} finally {
-			commitOrRollback(inTransaction, result);
-		}
-	}
+        } finally {
+            commitOrRollback(inTransaction, result);
+        }
+    }
 
-	@Override
-	public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean inTransaction) {
+    @Override
+    public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean inTransaction) {
 
-		Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
+        Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
 
-		try {
+        try {
 
-			Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
-					NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
+            Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
+                    NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
 
-			if (getResult.isRight()) {
-				TitanOperationStatus status = getResult.right().value();
-				if (status == TitanOperationStatus.NOT_FOUND) {
-					return Either.right(StorageOperationStatus.OK);
-				} else {
-					BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("DeleteAdditionalInformationNode", "additional information of " + nodeType.getName() + " " + resourceId, String.valueOf(status));
-					result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-				}
-				return result;
-			}
+            if (getResult.isRight()) {
+                TitanOperationStatus status = getResult.right().value();
+                if (status == TitanOperationStatus.NOT_FOUND) {
+                    return Either.right(StorageOperationStatus.OK);
+                } else {
+                    BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("DeleteAdditionalInformationNode", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + resourceId, String.valueOf(status));
+                    result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+                }
+                return result;
+            }
 
-			ImmutablePair<AdditionalInfoParameterData, GraphEdge> value = getResult.left().value();
-			AdditionalInfoParameterData parameterData = value.getLeft();
+            ImmutablePair<AdditionalInfoParameterData, GraphEdge> value = getResult.left().value();
+            AdditionalInfoParameterData parameterData = value.getLeft();
 
-			Either<AdditionalInfoParameterData, TitanOperationStatus> deleteNodeRes = titanGenericDao.deleteNode(parameterData, AdditionalInfoParameterData.class);
-			if (deleteNodeRes.isRight()) {
-				TitanOperationStatus status = getResult.right().value();
-				BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("DeleteAdditionalInformationNode", (String) parameterData.getUniqueId(), String.valueOf(status));
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-				return result;
-			}
+            Either<AdditionalInfoParameterData, TitanOperationStatus> deleteNodeRes = titanGenericDao.deleteNode(parameterData, AdditionalInfoParameterData.class);
+            if (deleteNodeRes.isRight()) {
+                TitanOperationStatus status = getResult.right().value();
+                BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("DeleteAdditionalInformationNode", (String) parameterData.getUniqueId(), String.valueOf(status));
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+                return result;
+            }
 
-			AdditionalInformationDefinition informationDefinition = convertAdditionalInformationDataToDefinition(deleteNodeRes.left().value(), resourceId);
+            AdditionalInformationDefinition informationDefinition = convertAdditionalInformationDataToDefinition(deleteNodeRes.left().value(), resourceId);
 
-			result = Either.left(informationDefinition);
+            result = Either.left(informationDefinition);
 
-			return result;
+            return result;
 
-		} finally {
-			commitOrRollback(inTransaction, result);
-		}
-	}
+        } finally {
+            commitOrRollback(inTransaction, result);
+        }
+    }
 
-	private TitanOperationStatus verifyNodeTypeVsComponent(NodeTypeEnum nodeType, String componentId) {
-		Either<TitanVertex, TitanOperationStatus> vertexByProperty = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId);
-		if (vertexByProperty.isRight()) {
-			TitanOperationStatus status = vertexByProperty.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			return status;
-		} else {
-			Vertex v = vertexByProperty.left().value();
-			String label = (String) v.property(GraphPropertiesDictionary.LABEL.getProperty()).value();
-			if (label != null) {
-				if (false == label.equals(nodeType.getName())) {
-					log.debug("The node type {} is not appropriate to component {}", nodeType, componentId);
-					return TitanOperationStatus.INVALID_ID;
-				}
-			} else {
-				log.debug("The node type {}  with id {} does not have a label property.", nodeType, componentId);
-				return TitanOperationStatus.INVALID_ID;
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus verifyNodeTypeVsComponent(NodeTypeEnum nodeType, String componentId) {
+        Either<TitanVertex, TitanOperationStatus> vertexByProperty = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId);
+        if (vertexByProperty.isRight()) {
+            TitanOperationStatus status = vertexByProperty.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            return status;
+        } else {
+            Vertex v = vertexByProperty.left().value();
+            String label = (String) v.property(GraphPropertiesDictionary.LABEL.getProperty()).value();
+            if (label != null) {
+                if (!label.equals(nodeType.getName())) {
+                    log.debug("The node type {} is not appropriate to component {}", nodeType, componentId);
+                    return TitanOperationStatus.INVALID_ID;
+                }
+            } else {
+                log.debug("The node type {}  with id {} does not have a label property.", nodeType, componentId);
+                return TitanOperationStatus.INVALID_ID;
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AnnotationTypeOperations.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AnnotationTypeOperations.java
new file mode 100644
index 0000000..988ff3c
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AnnotationTypeOperations.java
@@ -0,0 +1,64 @@
+package org.openecomp.sdc.be.model.operations.impl;
+
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.AnnotationTypeDefinition;
+import org.openecomp.sdc.be.model.operations.api.TypeOperations;
+import org.openecomp.sdc.be.resources.data.AnnotationTypeData;
+import org.springframework.stereotype.Component;
+
+import javax.validation.constraints.NotNull;
+
+@Component
+public class AnnotationTypeOperations implements TypeOperations<AnnotationTypeDefinition> {
+
+    private final CommonTypeOperations commonTypeOperations;
+
+    public AnnotationTypeOperations(CommonTypeOperations commonTypeOperations) {
+        this.commonTypeOperations = commonTypeOperations;
+    }
+
+    @Override
+    public AnnotationTypeDefinition addType(AnnotationTypeDefinition newTypeDefinition) {
+        AnnotationTypeData annotationTypeData = new AnnotationTypeData(newTypeDefinition);
+        String uniqueId = UniqueIdBuilder.buildTypeUid(newTypeDefinition.getType(), newTypeDefinition.getVersion(), "annotationtype");
+        annotationTypeData.setInitialCreationProperties(uniqueId);
+        commonTypeOperations.addType(annotationTypeData, AnnotationTypeData.class);
+        commonTypeOperations.addProperties(uniqueId, NodeTypeEnum.AnnotationType, newTypeDefinition.getProperties());
+        return getType(uniqueId);
+    }
+
+    @Override
+    public AnnotationTypeDefinition getType(String uniqueId) {
+        return commonTypeOperations.getType(uniqueId, AnnotationTypeData.class, NodeTypeEnum.AnnotationType)
+                .map(this::populateTypeDefinition)
+                .orElse(null);
+    }
+
+    private AnnotationTypeDefinition populateTypeDefinition(@NotNull AnnotationTypeData annotationTypeData) {
+        AnnotationTypeDefinition annotationTypeDefinition = new AnnotationTypeDefinition(annotationTypeData.getAnnotationTypeDataDefinition());
+        commonTypeOperations.fillProperties(annotationTypeDefinition.getUniqueId(), NodeTypeEnum.AnnotationType, annotationTypeDefinition::setProperties);
+        return annotationTypeDefinition;
+    }
+
+    @Override
+    public AnnotationTypeDefinition getLatestType(String type) {
+        return commonTypeOperations.getLatestType(type, AnnotationTypeData.class, NodeTypeEnum.AnnotationType)
+                .map(this::populateTypeDefinition)
+                .orElse(null);
+    }
+
+    @Override
+    public boolean isSameType(AnnotationTypeDefinition type1, AnnotationTypeDefinition type2) {
+        return type1.isSameDefinition(type2);
+    }
+
+    @Override
+    public AnnotationTypeDefinition updateType(AnnotationTypeDefinition currentTypeDefinition,
+                                               AnnotationTypeDefinition updatedTypeDefinition) {
+        AnnotationTypeData updatedTypeData = new AnnotationTypeData(updatedTypeDefinition);
+        updatedTypeData.setUpdateProperties(currentTypeDefinition);
+        commonTypeOperations.updateType(updatedTypeData, updatedTypeDefinition.getProperties(), AnnotationTypeData.class, NodeTypeEnum.AnnotationType);
+        return getType(updatedTypeData.getUniqueId());
+    }
+
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java
index 0c8abda..9beb205 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java
@@ -20,13 +20,9 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
@@ -53,702 +49,703 @@
 import org.openecomp.sdc.be.resources.data.HeatParameterValueData;
 import org.openecomp.sdc.be.resources.data.UniqueIdData;
 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.slf4j.MDC;
 import org.springframework.stereotype.Component;
 
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.util.*;
 
 @Component("artifact-operation")
 public class ArtifactOperation implements IArtifactOperation {
 
-	@javax.annotation.Resource
-	private TitanGenericDao titanGenericDao;
+    private static final String THE_RETURNED_ARTIFACT_DEFINTION_IS = "The returned ArtifactDefintion is {}";
 
 	@javax.annotation.Resource
-	private HeatParametersOperation heatParametersOperation;
+    private TitanGenericDao titanGenericDao;
 
-	@javax.annotation.Resource
-	private GroupOperation groupOperation;
-	@javax.annotation.Resource
-	private GroupInstanceOperation groupInstanceOperation;
+    @javax.annotation.Resource
+    private HeatParametersOperation heatParametersOperation;
 
-	private static Logger log = LoggerFactory.getLogger(ArtifactOperation.class.getName());
+    @javax.annotation.Resource
+    private GroupOperation groupOperation;
+    @javax.annotation.Resource
+    private GroupInstanceOperation groupInstanceOperation;
 
-	public ArtifactOperation() {
-		super();
-	}
+    private static final Logger log = Logger.getLogger(ArtifactOperation.class.getName());
 
-	public TitanGenericDao getTitanGenericDao() {
-		return titanGenericDao;
-	}
+    public ArtifactOperation() {
+        super();
+    }
 
-	public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
-		this.titanGenericDao = titanGenericDao;
-	}
+    public TitanGenericDao getTitanGenericDao() {
+        return titanGenericDao;
+    }
 
-	public HeatParametersOperation getHeatParametersOperation() {
-		return heatParametersOperation;
-	}
+    public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
+        this.titanGenericDao = titanGenericDao;
+    }
 
-	public void setHeatParametersOperation(HeatParametersOperation heatParametersOperation) {
-		this.heatParametersOperation = heatParametersOperation;
-	}
+    public HeatParametersOperation getHeatParametersOperation() {
+        return heatParametersOperation;
+    }
 
-	@Override
-	public Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, boolean inTransaction) {
+    public void setHeatParametersOperation(HeatParametersOperation heatParametersOperation) {
+        this.heatParametersOperation = heatParametersOperation;
+    }
 
-		Either<ArtifactData, StorageOperationStatus> status = addArtifactToGraph(artifactInfo, parentId, type, failIfExist);
+    @Override
+    public Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, boolean inTransaction) {
 
-		if (status.isRight()) {
-			if (false == inTransaction) {
-				titanGenericDao.rollback();
-			}
-			log.debug("Failed to add artifact {} to {} {}", artifactInfo.getArtifactName(), type , parentId);
-			return Either.right(status.right().value());
-		} else {
-			if (false == inTransaction) {
-				titanGenericDao.commit();
-			}
-			ArtifactData artifactData = status.left().value();
+        Either<ArtifactData, StorageOperationStatus> status = addArtifactToGraph(artifactInfo, parentId, type, failIfExist);
 
-			ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData);
+        if (status.isRight()) {
+            if (!inTransaction) {
+                titanGenericDao.rollback();
+            }
+            log.debug("Failed to add artifact {} to {} {}", artifactInfo.getArtifactName(), type , parentId);
+            return Either.right(status.right().value());
+        } else {
+            if (!inTransaction) {
+                titanGenericDao.commit();
+            }
+            ArtifactData artifactData = status.left().value();
 
-			log.debug("The returned ArtifactDefintion is {}", artifactDefResult);
-			return Either.left(artifactDefResult);
-		}
+            ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData);
 
-	}
+            log.debug(THE_RETURNED_ARTIFACT_DEFINTION_IS, artifactDefResult);
+            return Either.left(artifactDefResult);
+        }
 
-	@Override
-	public StorageOperationStatus addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, TitanVertex parentVertex) {
+    }
 
-		StorageOperationStatus status = addArtifactToGraph(artifactInfo, parentId, type, failIfExist, parentVertex);
+    @Override
+    public StorageOperationStatus addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, TitanVertex parentVertex) {
 
-		if (status.equals(StorageOperationStatus.OK)) {
-			log.debug("Failed to add artifact {} {} to {}", artifactInfo.getArtifactName(), type, parentId);
-		}
-		return status;
-	}
+        StorageOperationStatus status = addArtifactToGraph(artifactInfo, parentId, type, failIfExist, parentVertex);
 
-	private StorageOperationStatus addArtifactToGraph(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfexist, TitanVertex parentVertex) {
+        if (status.equals(StorageOperationStatus.OK)) {
+            log.debug("Failed to add artifact {} {} to {}", artifactInfo.getArtifactName(), type, parentId);
+        }
+        return status;
+    }
 
-		if (artifactInfo.getUniqueId() == null || artifactInfo.getUniqueId().isEmpty()) {
-			String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel());
-			artifactInfo.setUniqueId(uniqueId);
-		}
+    private StorageOperationStatus addArtifactToGraph(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfexist, TitanVertex parentVertex) {
 
-		if (validateParentType(type) == false) {
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
+        if (artifactInfo.getUniqueId() == null || artifactInfo.getUniqueId().isEmpty()) {
+            String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel());
+            artifactInfo.setUniqueId(uniqueId);
+        }
 
-		ArtifactData artifactData = new ArtifactData(artifactInfo);
+        if (!validateParentType(type)) {
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
 
-		Either<TitanVertex, TitanOperationStatus> existArtifact = titanGenericDao.getVertexByProperty(artifactData.getUniqueIdKey(), artifactData.getUniqueId());
-		if (existArtifact.isRight()) {
-			if (existArtifact.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
-				// create new node
-				log.debug("Before adding artifact to graph {}", artifactData);
-				if (artifactData.getArtifactDataDefinition().getArtifactUUID() == null || artifactData.getArtifactDataDefinition().getArtifactUUID().isEmpty())
-					updateUUID(artifactData.getArtifactDataDefinition(), null, artifactData.getArtifactDataDefinition().getArtifactVersion());
-				Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(artifactData);
+        ArtifactData artifactData = new ArtifactData(artifactInfo);
 
-				if (createNodeResult.isRight()) {
-					TitanOperationStatus operationStatus = createNodeResult.right().value();
-					log.debug("Failed to add artifact {} to graph. status is {}", artifactData.getArtifactDataDefinition().getArtifactName(), operationStatus);
-					BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add artifact", artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus));
-					return DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus);
-				}
+        Either<TitanVertex, TitanOperationStatus> existArtifact = titanGenericDao.getVertexByProperty(artifactData.getUniqueIdKey(), artifactData.getUniqueId());
+        if (existArtifact.isRight()) {
+            if (existArtifact.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
+                // create new node
+                log.debug("Before adding artifact to graph {}", artifactData);
+                if (artifactData.getArtifactDataDefinition().getArtifactUUID() == null || artifactData.getArtifactDataDefinition().getArtifactUUID().isEmpty())
+                    updateUUID(artifactData.getArtifactDataDefinition(), null, artifactData.getArtifactDataDefinition().getArtifactVersion());
+                Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(artifactData);
 
-				// add heat parameters
-				if (artifactInfo.getHeatParameters() != null && !artifactInfo.getHeatParameters().isEmpty() && !artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
-					StorageOperationStatus addPropertiesStatus = heatParametersOperation.addPropertiesToGraph(artifactInfo.getListHeatParameters(), artifactData.getUniqueId().toString(), NodeTypeEnum.ArtifactRef);
-					if (addPropertiesStatus != StorageOperationStatus.OK) {
-						log.debug("Failed to create heat parameters on graph for artifact {}", artifactInfo.getArtifactName());
-						return addPropertiesStatus;
-					}
-				}
+                if (createNodeResult.isRight()) {
+                    TitanOperationStatus operationStatus = createNodeResult.right().value();
+                    log.debug("Failed to add artifact {} to graph. status is {}", artifactData.getArtifactDataDefinition().getArtifactName(), operationStatus);
+                    BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add artifact", artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus));
+                    return DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus);
+                }
 
-			} else {
-				log.debug("Failed to check existance of artifact in graph for id {}", artifactData.getUniqueId());
-				return DaoStatusConverter.convertTitanStatusToStorageStatus(existArtifact.right().value());
-			}
-		} else if (failIfexist) {
-			log.debug("Artifact {} already exist", artifactData.getUniqueId());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ALREADY_EXIST);
-		}
+                // add heat parameters
+                if (artifactInfo.getHeatParameters() != null && !artifactInfo.getHeatParameters().isEmpty() && !artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
+                    StorageOperationStatus addPropertiesStatus = heatParametersOperation.addPropertiesToGraph(artifactInfo.getListHeatParameters(), artifactData.getUniqueId().toString(), NodeTypeEnum.ArtifactRef);
+                    if (addPropertiesStatus != StorageOperationStatus.OK) {
+                        log.debug("Failed to create heat parameters on graph for artifact {}", artifactInfo.getArtifactName());
+                        return addPropertiesStatus;
+                    }
+                }
 
-		// save logical artifact ref name on edge as property
-		Map<String, Object> properties = new HashMap<String, Object>();
-		properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), artifactInfo.getArtifactLabel());
-		if (artifactInfo.getArtifactGroupType() != null)
-			properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), artifactInfo.getArtifactGroupType().getType());
-		TitanOperationStatus relation = titanGenericDao.createEdge(parentVertex, artifactData, GraphEdgeLabels.ARTIFACT_REF, properties);
-		if (!relation.equals(TitanOperationStatus.OK)) {
-			log.debug("Failed to create relation in graph for id {} to new artifact", id);
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(relation);
-		}
+            } else {
+                log.debug("Failed to check existance of artifact in graph for id {}", artifactData.getUniqueId());
+                return DaoStatusConverter.convertTitanStatusToStorageStatus(existArtifact.right().value());
+            }
+        } else if (failIfexist) {
+            log.debug("Artifact {} already exist", artifactData.getUniqueId());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ALREADY_EXIST);
+        }
 
-		return StorageOperationStatus.OK;
-	}
+        // save logical artifact ref name on edge as property
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), artifactInfo.getArtifactLabel());
+        if (artifactInfo.getArtifactGroupType() != null)
+            properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), artifactInfo.getArtifactGroupType().getType());
+        TitanOperationStatus relation = titanGenericDao.createEdge(parentVertex, artifactData, GraphEdgeLabels.ARTIFACT_REF, properties);
+        if (!relation.equals(TitanOperationStatus.OK)) {
+            log.debug("Failed to create relation in graph for id {} to new artifact", id);
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(relation);
+        }
 
-	private Either<ArtifactData, StorageOperationStatus> addArtifactToGraph(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfexist) {
+        return StorageOperationStatus.OK;
+    }
 
-		if (artifactInfo.getUniqueId() == null || artifactInfo.getUniqueId().isEmpty()) {
-			String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel());
-			artifactInfo.setUniqueId(uniqueId);
-		}
+    private Either<ArtifactData, StorageOperationStatus> addArtifactToGraph(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfexist) {
 
-		if (validateParentType(type) == false) {
-			return Either.right(StorageOperationStatus.GENERAL_ERROR);
-		}
+        if (artifactInfo.getUniqueId() == null || artifactInfo.getUniqueId().isEmpty()) {
+            String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel());
+            artifactInfo.setUniqueId(uniqueId);
+        }
 
-		ArtifactData artifactData = new ArtifactData(artifactInfo);
+        if (!validateParentType(type)) {
+            return Either.right(StorageOperationStatus.GENERAL_ERROR);
+        }
 
-		Either<ArtifactData, TitanOperationStatus> existArtifact = titanGenericDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
-		if (existArtifact.isRight()) {
-			if (existArtifact.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
-				// create new node
-				log.debug("Before adding artifact to graph {}" , artifactData);
-				if (artifactData.getArtifactDataDefinition().getArtifactUUID() == null || artifactData.getArtifactDataDefinition().getArtifactUUID().isEmpty())
-					updateUUID(artifactData.getArtifactDataDefinition(), null, artifactData.getArtifactDataDefinition().getArtifactVersion());
-				Either<ArtifactData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(artifactData, ArtifactData.class);
-				log.debug("After adding artifact to graph {}", artifactData);
+        ArtifactData artifactData = new ArtifactData(artifactInfo);
 
-				if (createNodeResult.isRight()) {
-					TitanOperationStatus operationStatus = createNodeResult.right().value();
-					log.debug("Failed to add artifact {} to graph. status is {}", artifactData.getArtifactDataDefinition().getArtifactName(), operationStatus);
-					BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add artifact", artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus));
-					return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
-				}
-				artifactData = createNodeResult.left().value();
+        Either<ArtifactData, TitanOperationStatus> existArtifact = titanGenericDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
+        if (existArtifact.isRight()) {
+            if (existArtifact.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
+                // create new node
+                log.debug("Before adding artifact to graph {}" , artifactData);
+                if (artifactData.getArtifactDataDefinition().getArtifactUUID() == null || artifactData.getArtifactDataDefinition().getArtifactUUID().isEmpty())
+                    updateUUID(artifactData.getArtifactDataDefinition(), null, artifactData.getArtifactDataDefinition().getArtifactVersion());
+                Either<ArtifactData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(artifactData, ArtifactData.class);
+                log.debug("After adding artifact to graph {}", artifactData);
 
-				// add heat parameters
-				if (artifactInfo.getHeatParameters() != null && !artifactInfo.getHeatParameters().isEmpty() && !artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
-					StorageOperationStatus addPropertiesStatus = heatParametersOperation.addPropertiesToGraph(artifactInfo.getListHeatParameters(), artifactData.getUniqueId().toString(), NodeTypeEnum.ArtifactRef);
-					if (addPropertiesStatus != StorageOperationStatus.OK) {
-						log.debug("Failed to create heat parameters on graph for artifact {}", artifactInfo.getArtifactName());
-						return Either.right(addPropertiesStatus);
-					}
-				}
+                if (createNodeResult.isRight()) {
+                    TitanOperationStatus operationStatus = createNodeResult.right().value();
+                    log.debug("Failed to add artifact {} to graph. status is {}", artifactData.getArtifactDataDefinition().getArtifactName(), operationStatus);
+                    BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add artifact", artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus));
+                    return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
+                }
+                artifactData = createNodeResult.left().value();
 
-			} else {
-				log.debug("Failed to check existance of artifact in graph for id {}", artifactData.getUniqueId());
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(existArtifact.right().value()));
-			}
-		} else if (failIfexist) {
-			log.debug("Artifact {} already exist", artifactData.getUniqueId());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ALREADY_EXIST));
-		} else {
-			artifactData = existArtifact.left().value();
-		}
+                // add heat parameters
+                if (artifactInfo.getHeatParameters() != null && !artifactInfo.getHeatParameters().isEmpty() && !artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
+                    StorageOperationStatus addPropertiesStatus = heatParametersOperation.addPropertiesToGraph(artifactInfo.getListHeatParameters(), artifactData.getUniqueId().toString(), NodeTypeEnum.ArtifactRef);
+                    if (addPropertiesStatus != StorageOperationStatus.OK) {
+                        log.debug("Failed to create heat parameters on graph for artifact {}", artifactInfo.getArtifactName());
+                        return Either.right(addPropertiesStatus);
+                    }
+                }
 
-		UniqueIdData parent = new UniqueIdData(type, id);
+            } else {
+                log.debug("Failed to check existance of artifact in graph for id {}", artifactData.getUniqueId());
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(existArtifact.right().value()));
+            }
+        } else if (failIfexist) {
+            log.debug("Artifact {} already exist", artifactData.getUniqueId());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ALREADY_EXIST));
+        } else {
+            artifactData = existArtifact.left().value();
+        }
 
-		// save logical artifact ref name on edge as property
-		Map<String, Object> properties = new HashMap<String, Object>();
-		properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), artifactInfo.getArtifactLabel());
-		if (artifactInfo.getArtifactGroupType() != null)
-			properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), artifactInfo.getArtifactGroupType().getType());
-		Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation(parent, artifactData, GraphEdgeLabels.ARTIFACT_REF, properties);
-		if (relation.isRight()) {
-			log.debug("Failed to create relation in graph fro id {} to new artifact", id);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(relation.right().value()));
-		}
+        UniqueIdData parent = new UniqueIdData(type, id);
 
-		return Either.left(artifactData);
-	}
+        // save logical artifact ref name on edge as property
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), artifactInfo.getArtifactLabel());
+        if (artifactInfo.getArtifactGroupType() != null)
+            properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), artifactInfo.getArtifactGroupType().getType());
+        Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation(parent, artifactData, GraphEdgeLabels.ARTIFACT_REF, properties);
+        if (relation.isRight()) {
+            log.debug("Failed to create relation in graph fro id {} to new artifact", id);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(relation.right().value()));
+        }
 
-	private boolean validateParentType(NodeTypeEnum type) {
-		boolean isValid = false;
-		switch (type) {
-		case Resource:
-		case InterfaceOperation:
-		case Service:
-		case ResourceInstance:
-			isValid = true;
-			break;
-		default:
-			log.debug("Not supported node type for artifact relation : {} ", type);
-		}
-		return isValid;
-	}
-	
-	
-	protected ArtifactDefinition convertArtifactDataToArtifactDefinition(ArtifactData artifactDefResult) {
-		log.debug("The object returned after create property is {}" ,artifactDefResult);
+        return Either.left(artifactData);
+    }
 
-		ArtifactDefinition propertyDefResult = new ArtifactDefinition(artifactDefResult.getArtifactDataDefinition());
-		List<HeatParameterDefinition> parameters = new ArrayList<HeatParameterDefinition>();
-		StorageOperationStatus heatParametersOfNode = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefResult.getUniqueId().toString(), parameters);
-		if ((heatParametersOfNode.equals(StorageOperationStatus.OK)) && !parameters.isEmpty()) {
-			propertyDefResult.setListHeatParameters(parameters);
-		}
-		return propertyDefResult;
-	}
+    private boolean validateParentType(NodeTypeEnum type) {
+        boolean isValid = false;
+        switch (type) {
+        case Resource:
+        case InterfaceOperation:
+        case Service:
+        case ResourceInstance:
+            isValid = true;
+            break;
+        default:
+            log.debug("Not supported node type for artifact relation : {} ", type);
+        }
+        return isValid;
+    }
 
-	@Override
-	public Either<ArtifactDefinition, StorageOperationStatus> updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, boolean inTransaction) {
-		Either<ArtifactData, StorageOperationStatus> status = updateArtifactOnGraph(artifactInfo, artifactId, type, id);
 
-		if (status.isRight()) {
-			if (false == inTransaction) {
-				titanGenericDao.rollback();
-			}
-			log.debug("Failed to update artifact {} of {} {}. status is {}", artifactId, type.getName(), id, status.right().value());
-			BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactId, String.valueOf(status.right().value()));
-			return Either.right(status.right().value());
-		} else {
-			if (false == inTransaction) {
-				titanGenericDao.commit();
-			}
-			ArtifactData artifactData = status.left().value();
+    protected ArtifactDefinition convertArtifactDataToArtifactDefinition(ArtifactData artifactDefResult) {
+        log.debug("The object returned after create property is {}" ,artifactDefResult);
 
-			ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData);
-			log.debug("The returned ArtifactDefintion is {}", artifactDefResult);
-			return Either.left(artifactDefResult);
-		}
-	}
-	
-	@Override
-	public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact, boolean inTransaction) {
-		Either<ArtifactData, TitanOperationStatus> status = removeArtifactOnGraph(id, artifactId, type, deleteMandatoryArtifact);
+        ArtifactDefinition propertyDefResult = new ArtifactDefinition(artifactDefResult.getArtifactDataDefinition());
+        List<HeatParameterDefinition> parameters = new ArrayList<>();
+        StorageOperationStatus heatParametersOfNode = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefResult.getUniqueId().toString(), parameters);
+        if ((heatParametersOfNode.equals(StorageOperationStatus.OK)) && !parameters.isEmpty()) {
+            propertyDefResult.setListHeatParameters(parameters);
+        }
+        return propertyDefResult;
+    }
 
-		if (status.isRight()) {
-			if (false == inTransaction) {
-				titanGenericDao.rollback();
-			}
-			log.debug("Failed to delete artifact {} of resource {}", artifactId, id);
+    @Override
+    public Either<ArtifactDefinition, StorageOperationStatus> updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, boolean inTransaction) {
+        Either<ArtifactData, StorageOperationStatus> status = updateArtifactOnGraph(artifactInfo, artifactId, type, id);
 
-			BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete Artifact", artifactId, String.valueOf(status.right().value()));
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value()));
-		} else {
-			if (false == inTransaction) {
-				titanGenericDao.commit();
-			}
-			ArtifactData artifactData = status.left().value();
+        if (status.isRight()) {
+            if (!inTransaction) {
+                titanGenericDao.rollback();
+            }
+            log.debug("Failed to update artifact {} of {} {}. status is {}", artifactId, type.getName(), id, status.right().value());
+            BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactId, String.valueOf(status.right().value()));
+            return Either.right(status.right().value());
+        } else {
+            if (!inTransaction) {
+                titanGenericDao.commit();
+            }
+            ArtifactData artifactData = status.left().value();
 
-			ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData);
-			log.debug("The returned ArtifactDefintion is {}" , artifactDefResult);
-			return Either.left(artifactDefResult);
-		}
-	}
+            ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData);
+            log.debug(THE_RETURNED_ARTIFACT_DEFINTION_IS, artifactDefResult);
+            return Either.left(artifactDefResult);
+        }
+    }
 
-	@SuppressWarnings("null")
-	private Either<ArtifactData, StorageOperationStatus> updateArtifactOnGraph(ArtifactDefinition artifactInfo, String artifactId, NodeTypeEnum type, String id) {
+    @Override
+    public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact, boolean inTransaction) {
+        Either<ArtifactData, StorageOperationStatus> status = removeArtifactOnGraph(id, artifactId, type, deleteMandatoryArtifact);
 
-		Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
-		if (graph.isRight()) {
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value()));
-		}
+        if (status.isRight()) {
+            if (!inTransaction) {
+                titanGenericDao.rollback();
+            }
+            log.debug("Failed to delete artifact {} of resource {}", artifactId, id);
 
-		TitanGraph tGraph = graph.left().value();
+            BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete Artifact", artifactId, String.valueOf(status.right().value()));
+            return Either.right(status.right().value());
+        } else {
+            if (!inTransaction) {
+                titanGenericDao.commit();
+            }
+            ArtifactData artifactData = status.left().value();
 
-		@SuppressWarnings("unchecked")
-		Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices();
-		Iterator<TitanVertex> iterator = verticesArtifact.iterator();
-		if (!iterator.hasNext()) {
-			log.debug("No artifact node for id = {}", artifactId);
-			return Either.right(StorageOperationStatus.NOT_FOUND);
-		}
-		TitanVertex artifactV = iterator.next();
+            ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData);
+            log.debug(THE_RETURNED_ARTIFACT_DEFINTION_IS , artifactDefResult);
+            return Either.left(artifactDefResult);
+        }
+    }
 
-		Iterator<Edge> iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty());
+    @SuppressWarnings("null")
+    private Either<ArtifactData, StorageOperationStatus> updateArtifactOnGraph(ArtifactDefinition artifactInfo, String artifactId, NodeTypeEnum type, String id) {
 
-		int edgeCount = 0;
-		Edge edgeFromTo = null;
-		while (iterEdge.hasNext()) {
-			Edge edge = iterEdge.next();
-			Vertex vertexFrom = edge.outVertex();
-			String vertexId = vertexFrom.value(UniqueIdBuilder.getKeyByNodeType(type));
-			if (id.equals(vertexId)) {
-				edgeFromTo = edge;
-			}
-			++edgeCount;
-		}
-		
-		if (isNeedUpdateHeatTime(artifactInfo)) {
-			artifactInfo.setHeatParamsUpdateDate(System.currentTimeMillis());
-		}
+        Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
+        if (graph.isRight()) {
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value()));
+        }
 
-		ArtifactData artifactData = new ArtifactData(artifactInfo);
-		if (edgeFromTo == null) {
-			log.debug("No relation between artifact  = {} and node with id = {}", artifactId, id);
-			return Either.right(StorageOperationStatus.GENERAL_ERROR);
-		}
+        TitanGraph tGraph = graph.left().value();
 
-		Either<Boolean, StorageOperationStatus> setRelevantHeatParamIdRes = null;
-		if (edgeCount > 1) {
-			// need to remove relation, create new node
-			log.debug("artifactRef have more connection. Need to clone node");
-			log.debug("remove edge {}", edgeFromTo);
-			edgeFromTo.remove();
-			// update resource id in new artifact node
-			String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel());
-			artifactInfo.setUniqueId(uniqueId);
-			// update UUID and artifact version
-			String oldChecksum = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_CHECKSUM.getProperty()));
-			String oldVersion = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_VERSION.getProperty()));
-			updateUUID(artifactInfo, oldChecksum, oldVersion);
-			log.debug("try to create new artifact ref node for id {}", uniqueId);
-			Either<ArtifactData, StorageOperationStatus> addedArtifactRes = addArtifactToGraph(artifactInfo, id, type, true);
+        @SuppressWarnings("unchecked")
+        Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices();
+        Iterator<TitanVertex> iterator = verticesArtifact.iterator();
+        if (!iterator.hasNext()) {
+            log.debug("No artifact node for id = {}", artifactId);
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        TitanVertex artifactV = iterator.next();
 
-			if (addedArtifactRes.isLeft()) {
-				// remove all relations between groups to the old artifact
-				// add relation between the same groups to the new artifact
-				StorageOperationStatus reassociateGroupsFromArtifact = groupOperation.dissociateAndAssociateGroupsFromArtifact(id, type, artifactId, addedArtifactRes.left().value(), true);
-				if (reassociateGroupsFromArtifact != StorageOperationStatus.OK) {
-					BeEcompErrorManager.getInstance().logInternalFlowError("UpdateArtifact", "Failed to reassociate groups to the new artifact", ErrorSeverity.ERROR);
-					return Either.right(reassociateGroupsFromArtifact);
-				}
-				
-				StorageOperationStatus reassociateGroupInstancesFromArtifact = groupInstanceOperation.dissociateAndAssociateGroupsInstanceFromArtifact(id, type, artifactId, addedArtifactRes.left().value());
-				if (reassociateGroupInstancesFromArtifact != StorageOperationStatus.OK) {
-					BeEcompErrorManager.getInstance().logInternalFlowError("UpdateArtifact", "Failed to reassociate group instances to the new artifact", ErrorSeverity.ERROR);
-					return Either.right(reassociateGroupsFromArtifact);
-				}
-				
-				// If artifact is heat env
-				if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
-					ArtifactData addedArtifact = addedArtifactRes.left().value();
-					String newArtifactUniqueId = (String) addedArtifact.getUniqueId();
-					Either<HeatParameterValueData, StorageOperationStatus> updateResult = null;
+        Iterator<Edge> iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty());
 
-					setRelevantHeatParamIdRes = setRelevantHeatParamId(artifactV, artifactInfo);
-					if (setRelevantHeatParamIdRes.isRight()) {
-						log.error("Failed to set relevant id to heat parameters for heat env artifact {}. Status is {}", artifactInfo.getUniqueId(), setRelevantHeatParamIdRes.right().value());
-						return Either.right(setRelevantHeatParamIdRes.right().value());
-					}
-					for (HeatParameterDefinition heatEnvParam : artifactInfo.getListHeatParameters()) {
-						updateResult = heatParametersOperation.updateHeatParameterValue(heatEnvParam, newArtifactUniqueId, id, artifactInfo.getArtifactLabel());
-						if (updateResult.isRight()) {
-							log.error("Failed to update heat parameter {}. Status is {}", heatEnvParam.getName(), updateResult.right().value());
-							return Either.right(updateResult.right().value());
-						}
-					}
+        int edgeCount = 0;
+        Edge edgeFromTo = null;
+        while (iterEdge.hasNext()) {
+            Edge edge = iterEdge.next();
+            Vertex vertexFrom = edge.outVertex();
+            String vertexId = vertexFrom.value(UniqueIdBuilder.getKeyByNodeType(type));
+            if (id.equals(vertexId)) {
+                edgeFromTo = edge;
+            }
+            ++edgeCount;
+        }
+
+        if (isNeedUpdateHeatTime(artifactInfo)) {
+            artifactInfo.setHeatParamsUpdateDate(System.currentTimeMillis());
+        }
+
+        ArtifactData artifactData = new ArtifactData(artifactInfo);
+        if (edgeFromTo == null) {
+            log.debug("No relation between artifact  = {} and node with id = {}", artifactId, id);
+            return Either.right(StorageOperationStatus.GENERAL_ERROR);
+        }
+
+        Either<Boolean, StorageOperationStatus> setRelevantHeatParamIdRes = null;
+        if (edgeCount > 1) {
+            // need to remove relation, create new node
+            log.debug("artifactRef have more connection. Need to clone node");
+            log.debug("remove edge {}", edgeFromTo);
+            edgeFromTo.remove();
+            // update resource id in new artifact node
+            String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel());
+            artifactInfo.setUniqueId(uniqueId);
+            // update UUID and artifact version
+            String oldChecksum = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_CHECKSUM.getProperty()));
+            String oldVersion = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_VERSION.getProperty()));
+            updateUUID(artifactInfo, oldChecksum, oldVersion);
+            log.debug("try to create new artifact ref node for id {}", uniqueId);
+            Either<ArtifactData, StorageOperationStatus> addedArtifactRes = addArtifactToGraph(artifactInfo, id, type, true);
+
+            if (addedArtifactRes.isLeft()) {
+                // remove all relations between groups to the old artifact
+                // add relation between the same groups to the new artifact
+                StorageOperationStatus reassociateGroupsFromArtifact = groupOperation.dissociateAndAssociateGroupsFromArtifact(id, type, artifactId, addedArtifactRes.left().value(), true);
+                if (reassociateGroupsFromArtifact != StorageOperationStatus.OK) {
+                    BeEcompErrorManager.getInstance().logInternalFlowError("UpdateArtifact", "Failed to reassociate groups to the new artifact", ErrorSeverity.ERROR);
+                    return Either.right(reassociateGroupsFromArtifact);
+                }
+
+                StorageOperationStatus reassociateGroupInstancesFromArtifact = groupInstanceOperation.dissociateAndAssociateGroupsInstanceFromArtifact(id, type, artifactId, addedArtifactRes.left().value());
+                if (reassociateGroupInstancesFromArtifact != StorageOperationStatus.OK) {
+                    BeEcompErrorManager.getInstance().logInternalFlowError("UpdateArtifact", "Failed to reassociate group instances to the new artifact", ErrorSeverity.ERROR);
+                    return Either.right(reassociateGroupsFromArtifact);
+                }
+
+                // If artifact is heat env
+                if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
+                    ArtifactData addedArtifact = addedArtifactRes.left().value();
+                    String newArtifactUniqueId = addedArtifact.getUniqueId();
+                    Either<HeatParameterValueData, StorageOperationStatus> updateResult = null;
+
+                    setRelevantHeatParamIdRes = setRelevantHeatParamId(artifactV, artifactInfo);
+                    if (setRelevantHeatParamIdRes.isRight()) {
+                        log.error("Failed to set relevant id to heat parameters for heat env artifact {}. Status is {}", artifactInfo.getUniqueId(), setRelevantHeatParamIdRes.right().value());
+                        return Either.right(setRelevantHeatParamIdRes.right().value());
+                    }
+                    for (HeatParameterDefinition heatEnvParam : artifactInfo.getListHeatParameters()) {
+                        updateResult = heatParametersOperation.updateHeatParameterValue(heatEnvParam, newArtifactUniqueId, id, artifactInfo.getArtifactLabel());
+                        if (updateResult.isRight()) {
+                            log.error("Failed to update heat parameter {}. Status is {}", heatEnvParam.getName(), updateResult.right().value());
+                            return Either.right(updateResult.right().value());
+                        }
+                    }
 
-					Iterator<Edge> iterEdgeGeneratedFrom = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty());
+                    Iterator<Edge> iterEdgeGeneratedFrom = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty());
 
-					if (!iterEdgeGeneratedFrom.hasNext()) {
-						log.error("No heat artifact node for id = {}", artifactId);
-						return Either.right(StorageOperationStatus.NOT_FOUND);
-					}
-					Edge edgeToHeat = iterEdgeGeneratedFrom.next();
-					Vertex vertexIn = edgeToHeat.inVertex();
-					String generatedFromArtifactId = vertexIn.value(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef));
-					UniqueIdData generatedFromArtifactNode = new UniqueIdData(NodeTypeEnum.ArtifactRef, generatedFromArtifactId);
-					Either<GraphRelation, TitanOperationStatus> createRelationToGeneratedFromArtifactRes = titanGenericDao.createRelation(addedArtifact, generatedFromArtifactNode, GraphEdgeLabels.GENERATED_FROM, null);
-					if (createRelationToGeneratedFromArtifactRes.isRight()) {
-						log.error("Failed to create relation from heat_env {} to heat {}", addedArtifact.getUniqueId(), generatedFromArtifactNode);
-						return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createRelationToGeneratedFromArtifactRes.right().value()));
-					}
-				}
-			}
-			return addedArtifactRes;
+                    if (!iterEdgeGeneratedFrom.hasNext()) {
+                        log.error("No heat artifact node for id = {}", artifactId);
+                        return Either.right(StorageOperationStatus.NOT_FOUND);
+                    }
+                    Edge edgeToHeat = iterEdgeGeneratedFrom.next();
+                    Vertex vertexIn = edgeToHeat.inVertex();
+                    String generatedFromArtifactId = vertexIn.value(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef));
+                    UniqueIdData generatedFromArtifactNode = new UniqueIdData(NodeTypeEnum.ArtifactRef, generatedFromArtifactId);
+                    Either<GraphRelation, TitanOperationStatus> createRelationToGeneratedFromArtifactRes = titanGenericDao.createRelation(addedArtifact, generatedFromArtifactNode, GraphEdgeLabels.GENERATED_FROM, null);
+                    if (createRelationToGeneratedFromArtifactRes.isRight()) {
+                        log.error("Failed to create relation from heat_env {} to heat {}", addedArtifact.getUniqueId(), generatedFromArtifactNode);
+                        return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createRelationToGeneratedFromArtifactRes.right().value()));
+                    }
+                }
+            }
+            return addedArtifactRes;
 
-		} else {
-			if (edgeCount == 1) {
-				String oldChecksum = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_CHECKSUM.getProperty()));
-				String oldVersion = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_VERSION.getProperty()));
-				updateUUID(artifactInfo, oldChecksum, oldVersion);
-				// update exist
-				Either<ArtifactData, TitanOperationStatus> updatedArtifact = titanGenericDao.updateNode(artifactData, ArtifactData.class);
-				if (updatedArtifact.isRight()) {
-					log.debug("failed to update artifact node for id {}", artifactData.getUniqueId());
-					return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updatedArtifact.right().value()));
-				}
+        } else {
+            if (edgeCount == 1) {
+                String oldChecksum = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_CHECKSUM.getProperty()));
+                String oldVersion = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_VERSION.getProperty()));
+                updateUUID(artifactInfo, oldChecksum, oldVersion);
+                // update exist
+                Either<ArtifactData, TitanOperationStatus> updatedArtifact = titanGenericDao.updateNode(artifactData, ArtifactData.class);
+                if (updatedArtifact.isRight()) {
+                    log.debug("failed to update artifact node for id {}", artifactData.getUniqueId());
+                    return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updatedArtifact.right().value()));
+                }
 
-				if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
-					Either<HeatParameterValueData, StorageOperationStatus> updateResult = null;
-					String artifactUniqueId = artifactInfo.getUniqueId();
-					setRelevantHeatParamIdRes = setRelevantHeatParamId(artifactV, artifactInfo);
-					if (setRelevantHeatParamIdRes.isRight()) {
-						log.error("Failed to set relevant id to heat parameters for heat env artifact {}. Status is {}", artifactInfo.getUniqueId(), setRelevantHeatParamIdRes.right().value());
-						return Either.right(setRelevantHeatParamIdRes.right().value());
-					}
-					for (HeatParameterDefinition heatEnvParam : artifactInfo.getListHeatParameters()) {
-						updateResult = heatParametersOperation.updateHeatParameterValue(heatEnvParam, artifactUniqueId, id, artifactInfo.getArtifactLabel());
-						if (updateResult.isRight()) {
-							log.error("Failed to update heat parameter {}. Status is {}", heatEnvParam.getName(), updateResult.right().value());
-							return Either.right(updateResult.right().value());
-						}
-					}
-				} else {
-					if (artifactData.getArtifactDataDefinition().getArtifactChecksum() == null) {
-						// update heat parameters only if it is not heat env
-						if (artifactInfo.getGeneratedFromId() == null) {
-							StorageOperationStatus operationStatus = heatParametersOperation.updateHeatParameters(artifactInfo.getListHeatParameters());
-							if (operationStatus != StorageOperationStatus.OK) {
-								return Either.right(operationStatus);
-							}
-						}
-					} else {
-						Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteParameters = heatParametersOperation.deleteAllHeatParametersAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactInfo.getUniqueId());
-						if (deleteParameters.isRight()) {
-							log.debug("failed to update heat parameters for artifact id {}", artifactData.getUniqueId());
-							return Either.right(StorageOperationStatus.GENERAL_ERROR);
-						}
+                if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
+                    Either<HeatParameterValueData, StorageOperationStatus> updateResult = null;
+                    String artifactUniqueId = artifactInfo.getUniqueId();
+                    setRelevantHeatParamIdRes = setRelevantHeatParamId(artifactV, artifactInfo);
+                    if (setRelevantHeatParamIdRes.isRight()) {
+                        log.error("Failed to set relevant id to heat parameters for heat env artifact {}. Status is {}", artifactInfo.getUniqueId(), setRelevantHeatParamIdRes.right().value());
+                        return Either.right(setRelevantHeatParamIdRes.right().value());
+                    }
+                    for (HeatParameterDefinition heatEnvParam : artifactInfo.getListHeatParameters()) {
+                        updateResult = heatParametersOperation.updateHeatParameterValue(heatEnvParam, artifactUniqueId, id, artifactInfo.getArtifactLabel());
+                        if (updateResult.isRight()) {
+                            log.error("Failed to update heat parameter {}. Status is {}", heatEnvParam.getName(), updateResult.right().value());
+                            return Either.right(updateResult.right().value());
+                        }
+                    }
+                } else {
+                    if (artifactData.getArtifactDataDefinition().getArtifactChecksum() == null) {
+                        // update heat parameters only if it is not heat env
+                        if (artifactInfo.getGeneratedFromId() == null) {
+                            StorageOperationStatus operationStatus = heatParametersOperation.updateHeatParameters(artifactInfo.getListHeatParameters());
+                            if (operationStatus != StorageOperationStatus.OK) {
+                                return Either.right(operationStatus);
+                            }
+                        }
+                    } else {
+                        Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteParameters = heatParametersOperation.deleteAllHeatParametersAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactInfo.getUniqueId());
+                        if (deleteParameters.isRight()) {
+                            log.debug("failed to update heat parameters for artifact id {}", artifactData.getUniqueId());
+                            return Either.right(StorageOperationStatus.GENERAL_ERROR);
+                        }
 
-						StorageOperationStatus addParameters = heatParametersOperation.addPropertiesToGraph(artifactInfo.getListHeatParameters(), artifactId, NodeTypeEnum.ArtifactRef);
-						if (!addParameters.equals(StorageOperationStatus.OK)) {
-							log.debug("failed to update heat parameters for artifact id {}", artifactData.getUniqueId());
-							return Either.right(StorageOperationStatus.GENERAL_ERROR);
-						}
+                        StorageOperationStatus addParameters = heatParametersOperation.addPropertiesToGraph(artifactInfo.getListHeatParameters(), artifactId, NodeTypeEnum.ArtifactRef);
+                        if (!addParameters.equals(StorageOperationStatus.OK)) {
+                            log.debug("failed to update heat parameters for artifact id {}", artifactData.getUniqueId());
+                            return Either.right(StorageOperationStatus.GENERAL_ERROR);
+                        }
 
-					}
-				}
+                    }
+                }
 
-				return Either.left(updatedArtifact.left().value());
-			} else {
-				log.debug("No relevent edges for artifact = {}", artifactId);
-				return Either.right(StorageOperationStatus.GENERAL_ERROR);
-			}
-		}
-	}
+                return Either.left(updatedArtifact.left().value());
+            } else {
+                log.debug("No relevent edges for artifact = {}", artifactId);
+                return Either.right(StorageOperationStatus.GENERAL_ERROR);
+            }
+        }
+    }
 
-	private boolean isNeedUpdateHeatTime(ArtifactDefinition artifactInfo) {
-		if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType()) || artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_VOL.getType())) {
-			return true;
-		}
-		return false;
-	}
+    private boolean isNeedUpdateHeatTime(ArtifactDefinition artifactInfo) {
+        if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType()) || artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_VOL.getType())) {
+            return true;
+        }
+        return false;
+    }
 
-	private Either<Boolean, StorageOperationStatus> setRelevantHeatParamId(TitanVertex artifactV, ArtifactDefinition artifactInfo) {
+    private Either<Boolean, StorageOperationStatus> setRelevantHeatParamId(TitanVertex artifactV, ArtifactDefinition artifactInfo) {
 
-		Map<String, String> heatParametersHM = new HashMap<String, String>();
+        Map<String, String> heatParametersHM = new HashMap<>();
 
-		Iterator<Edge> iterHeat = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty());
-		if (!iterHeat.hasNext()) {
-			log.debug("No edges with label GENERATED_FROM for the node {}" , artifactInfo.getUniqueId());
-			return Either.right(StorageOperationStatus.NOT_FOUND);
-		}
-		Edge heat = iterHeat.next();
-		Vertex heatVertex = heat.inVertex();
-		String heatUniqueId = (String) heatVertex.value(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef));
+        Iterator<Edge> iterHeat = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty());
+        if (!iterHeat.hasNext()) {
+            log.debug("No edges with label GENERATED_FROM for the node {}" , artifactInfo.getUniqueId());
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        Edge heat = iterHeat.next();
+        Vertex heatVertex = heat.inVertex();
+        String heatUniqueId = (String) heatVertex.value(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef));
 
-		Either<List<ImmutablePair<HeatParameterData, GraphEdge>>, TitanOperationStatus> getHeatParametersRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), heatUniqueId, GraphEdgeLabels.HEAT_PARAMETER,
-				NodeTypeEnum.HeatParameter, HeatParameterData.class);
-		if (getHeatParametersRes.isRight()) {
-			log.debug("No heat parameters for heat artifact {}", heatUniqueId);
-			return Either.right(StorageOperationStatus.NOT_FOUND);
-		}
-		List<ImmutablePair<HeatParameterData, GraphEdge>> heatParameters = getHeatParametersRes.left().value();
-		if (heatParameters == null) {
-			log.debug("No heat parameters for heat artifact {}", heatUniqueId);
-			return Either.right(StorageOperationStatus.NOT_FOUND);
-		}
-		for (ImmutablePair<HeatParameterData, GraphEdge> heatParamEdge : heatParameters) {
-			HeatParameterData heatParam = heatParamEdge.getLeft();
-			heatParametersHM.put(heatParam.getName(), (String) heatParam.getUniqueId());
-		}
-		String curName = null;
-		for (HeatParameterDefinition heatEnvParam : artifactInfo.getListHeatParameters()) {
-			curName = heatEnvParam.getName();
-			if (heatParametersHM.containsKey(curName)) {
-				heatEnvParam.setUniqueId(heatParametersHM.get(curName));
-			}
-		}
-		return Either.left(true);
-	}
+        Either<List<ImmutablePair<HeatParameterData, GraphEdge>>, TitanOperationStatus> getHeatParametersRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), heatUniqueId, GraphEdgeLabels.HEAT_PARAMETER,
+                NodeTypeEnum.HeatParameter, HeatParameterData.class);
+        if (getHeatParametersRes.isRight()) {
+            log.debug("No heat parameters for heat artifact {}", heatUniqueId);
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        List<ImmutablePair<HeatParameterData, GraphEdge>> heatParameters = getHeatParametersRes.left().value();
+        if (heatParameters == null) {
+            log.debug("No heat parameters for heat artifact {}", heatUniqueId);
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        for (ImmutablePair<HeatParameterData, GraphEdge> heatParamEdge : heatParameters) {
+            HeatParameterData heatParam = heatParamEdge.getLeft();
+            heatParametersHM.put(heatParam.getName(), (String) heatParam.getUniqueId());
+        }
+        String curName = null;
+        for (HeatParameterDefinition heatEnvParam : artifactInfo.getListHeatParameters()) {
+            curName = heatEnvParam.getName();
+            if (heatParametersHM.containsKey(curName)) {
+                heatEnvParam.setUniqueId(heatParametersHM.get(curName));
+            }
+        }
+        return Either.left(true);
+    }
 
-	private Either<ArtifactData, TitanOperationStatus> removeArtifactOnGraph(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
-		Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
-		if (graph.isRight()) {
-			return Either.right(graph.right().value());
-		}
+    private Either<ArtifactData, StorageOperationStatus> removeArtifactOnGraph(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
+        Either<TitanGraph, StorageOperationStatus> graph = titanGenericDao.getGraph()
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+        if (graph.isRight()) {
+            return Either.right(graph.right().value());
+        }
 
-		TitanGraph tGraph = graph.left().value();
-		Either<ArtifactData, TitanOperationStatus> artifactData = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, ArtifactData.class);
-		if (artifactData.isRight()) {
-			log.debug("Failed to retrieve  artifact for id = {}", artifactId);
-			return Either.right(artifactData.right().value());
-		}
-		ArtifactDataDefinition artifactDefinition = artifactData.left().value().getArtifactDataDefinition();
-		boolean isMandatory = false;
-		if ((artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) && !deleteMandatoryArtifact) {
-			// return Either.left(artifactData.left().value());
-			isMandatory = true;
-		}
+        TitanGraph tGraph = graph.left().value();
+        Either<ArtifactData, StorageOperationStatus> artifactData = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, ArtifactData.class)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+        if (artifactData.isRight()) {
+            log.debug("Failed to retrieve  artifact for id = {}", artifactId);
+            return Either.right(artifactData.right().value());
+        }
+        ArtifactDataDefinition artifactDefinition = artifactData.left().value().getArtifactDataDefinition();
+        boolean isMandatory = false;
+        if ((artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) && !deleteMandatoryArtifact) {
+            isMandatory = true;
+        }
 
-		@SuppressWarnings("unchecked")
-		Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices();
-		Iterator<TitanVertex> iterator = verticesArtifact.iterator();
-		if (!iterator.hasNext()) {
-			log.debug("No artifact node for id = {}", artifactId);
-			return Either.right(TitanOperationStatus.NOT_FOUND);
-		}
-		Vertex artifactV = iterator.next();
-		Iterator<Edge> iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty());
-		int edgeCount = 0;
-		Edge edgeFromTo = null;
-		while (iterEdge.hasNext()) {
-			Edge edge = iterEdge.next();
-			Vertex vertexFrom = edge.outVertex();
-			String vertexId = vertexFrom.value(UniqueIdBuilder.getKeyByNodeType(type));
-			if (id.equals(vertexId)) {
-				edgeFromTo = edge;
-			}
-			++edgeCount;
-		}
-		if (edgeFromTo == null) {
-			log.debug("No relation between artifact  = {} and node with id = {}", artifactId, id);
-			return Either.right(TitanOperationStatus.GENERAL_ERROR);
-		}
+        @SuppressWarnings("unchecked")
+        Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices();
+        Iterator<TitanVertex> iterator = verticesArtifact.iterator();
+        if (!iterator.hasNext()) {
+            log.debug("No artifact node for id = {}", artifactId);
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        Vertex artifactV = iterator.next();
+        Iterator<Edge> iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty());
+        int edgeCount = 0;
+        Edge edgeFromTo = null;
+        while (iterEdge.hasNext()) {
+            Edge edge = iterEdge.next();
+            Vertex vertexFrom = edge.outVertex();
+            String vertexId = vertexFrom.value(UniqueIdBuilder.getKeyByNodeType(type));
+            if (id.equals(vertexId)) {
+                edgeFromTo = edge;
+            }
+            ++edgeCount;
+        }
+        if (edgeFromTo == null) {
+            log.debug("No relation between artifact  = {} and node with id = {}", artifactId, id);
+            return Either.right(StorageOperationStatus.GENERAL_ERROR);
+        }
 
-		// need to remove relation from resource/interface
+        // need to remove relation from resource/interface
 
-		log.debug("remove edge {}", edgeFromTo);
-		if (!isMandatory || (isMandatory && edgeCount > 1)) {
-			edgeFromTo.remove();
-		}
+        log.debug("remove edge {}", edgeFromTo);
+        if (!isMandatory || (isMandatory && edgeCount > 1)) {
+            edgeFromTo.remove();
+        }
 
-		// delete edges from all groups under the component id which related to
-		// this artifact.
-		// Also in case it is a mandatory artifact.
-		Either<List<GraphRelation>, TitanOperationStatus> dissociateAllGroups = groupOperation.dissociateAllGroupsFromArtifactOnGraph(id, type, artifactId);
-		if (dissociateAllGroups.isRight()) {
-			TitanOperationStatus status = dissociateAllGroups.right().value();
-			if (status != TitanOperationStatus.NOT_FOUND && status != TitanOperationStatus.OK) {
-				return Either.right(status);
-			}
-		}
+        // delete edges from all groups under the component id which related to
+        // this artifact.
+        // Also in case it is a mandatory artifact.
+        Either<List<GraphRelation>, StorageOperationStatus> dissociateAllGroups = groupOperation.dissociateAllGroupsFromArtifactOnGraph(id, type, artifactId);
+        if (dissociateAllGroups.isRight()) {
+            StorageOperationStatus status = dissociateAllGroups.right().value();
+            if (status != StorageOperationStatus.NOT_FOUND && status != StorageOperationStatus.OK) {
+                return Either.right(status);
+            }
+        }
 
-		if (edgeCount == 1) {
-			// remove artifactRef node
-			log.debug("Remove artifactRef node from graph");
-			Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteStatus = heatParametersOperation.deleteAllHeatParametersAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactId);
-			if (deleteStatus.isRight()) {
-				log.error("failed to delete heat parameters of artifact {}", artifactId);
-				return Either.right(TitanOperationStatus.GENERAL_ERROR);
-			}
+        if (edgeCount == 1) {
+            // remove artifactRef node
+            log.debug("Remove artifactRef node from graph");
+            Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteStatus = heatParametersOperation.deleteAllHeatParametersAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactId);
+            if (deleteStatus.isRight()) {
+                log.error("failed to delete heat parameters of artifact {}", artifactId);
+                return Either.right(StorageOperationStatus.GENERAL_ERROR);
+            }
 
-			StorageOperationStatus deleteValuesStatus = heatParametersOperation.deleteAllHeatValuesAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactId);
-			if (!deleteValuesStatus.equals(StorageOperationStatus.OK)) {
-				log.error("failed to delete heat values of artifact {}", artifactId);
-				return Either.right(TitanOperationStatus.GENERAL_ERROR);
-			}
-			if (!isMandatory) {
-				artifactV.remove();
-			}
-		} else {
-			log.debug("artifactRef have more connection. ArtifactRef node will not be removed ");
-		}
+            StorageOperationStatus deleteValuesStatus = heatParametersOperation.deleteAllHeatValuesAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactId);
+            if (!deleteValuesStatus.equals(StorageOperationStatus.OK)) {
+                log.error("failed to delete heat values of artifact {}", artifactId);
+                return Either.right(StorageOperationStatus.GENERAL_ERROR);
+            }
+            if (!isMandatory) {
+                artifactV.remove();
+            }
+        } else {
+            log.debug("artifactRef have more connection. ArtifactRef node will not be removed ");
+        }
 
-		return Either.left(artifactData.left().value());
+        return Either.left(artifactData.left().value());
 
-	}
+    }
 
-	/**
-	 * 
-	 * @param parentId
-	 * @param parentType
-	 * @param inTransaction
-	 * @return
-	 */
-	public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction) {
-		Either<Map<String, ArtifactDefinition>, StorageOperationStatus> result = null;
-		try {
-			Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
-			if (graph.isRight()) {
-				log.debug("Failed to work with graph {}", graph.right().value());
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value()));
-			}
-			TitanGraph tGraph = graph.left().value();
-			@SuppressWarnings("unchecked")
-			Iterable<TitanVertex> vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices();
-			if (vertices == null) {
-				log.debug("No nodes for type {}  for id = {}", parentType, parentId);
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-				return result;
-			}
-			Iterator<TitanVertex> iterator = vertices.iterator();
+    /**
+     *
+     * @param parentId
+     * @param parentType
+     * @param inTransaction
+     * @return
+     */
+    public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction) {
+        Either<Map<String, ArtifactDefinition>, StorageOperationStatus> result = null;
+        try {
+            Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
+            if (graph.isRight()) {
+                log.debug("Failed to work with graph {}", graph.right().value());
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value()));
+            }
+            TitanGraph tGraph = graph.left().value();
+            @SuppressWarnings("unchecked")
+            Iterable<TitanVertex> vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices();
+            if (vertices == null) {
+                log.debug("No nodes for type {}  for id = {}", parentType, parentId);
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+                return result;
+            }
+            Iterator<TitanVertex> iterator = vertices.iterator();
 
-			Map<String, ArtifactDefinition> artifactMap = new HashMap<String, ArtifactDefinition>();
-			while (iterator.hasNext()) {
-				Vertex vertex = iterator.next();
-				Iterator<Edge> iteratorEdge = vertex.edges(Direction.OUT, GraphEdgeLabels.ARTIFACT_REF.getProperty());
+            Map<String, ArtifactDefinition> artifactMap = new HashMap<>();
+            while (iterator.hasNext()) {
+                Vertex vertex = iterator.next();
+                Iterator<Edge> iteratorEdge = vertex.edges(Direction.OUT, GraphEdgeLabels.ARTIFACT_REF.getProperty());
 
-				if (iteratorEdge != null) {
+                if (iteratorEdge != null) {
 
-					while (iteratorEdge.hasNext()) {
-						Edge edge = iteratorEdge.next();
+                    while (iteratorEdge.hasNext()) {
+                        Edge edge = iteratorEdge.next();
 
-						Vertex artifactV = edge.inVertex();
+                        Vertex artifactV = edge.inVertex();
 
-						Map<String, Object> properties = this.titanGenericDao.getProperties(artifactV);
-						ArtifactData artifact = GraphElementFactory.createElement(NodeTypeEnum.ArtifactRef.getName(), GraphElementTypeEnum.Node, properties, ArtifactData.class);
-						if (artifact != null) {
+                        Map<String, Object> properties = this.titanGenericDao.getProperties(artifactV);
+                        ArtifactData artifact = GraphElementFactory.createElement(NodeTypeEnum.ArtifactRef.getName(), GraphElementTypeEnum.Node, properties, ArtifactData.class);
+                        if (artifact != null) {
 
-							ArtifactDefinition artifactDefinition = new ArtifactDefinition(artifact.getArtifactDataDefinition());
-							Iterator<Edge> edgesGeneratedFrom = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty());
-							if (edgesGeneratedFrom != null && edgesGeneratedFrom.hasNext()) {
-								TitanVertex inVertex = (TitanVertex) edgesGeneratedFrom.next().inVertex();
-								String artifactIdGeneratedFrom = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
-								artifactDefinition.setGeneratedFromId(artifactIdGeneratedFrom);
-							}
-							List<HeatParameterDefinition> heatParams = new ArrayList<HeatParameterDefinition>();
-							StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefinition.getUniqueId(), heatParams);
-							if (!heatParametersStatus.equals(StorageOperationStatus.OK)) {
-								log.debug("failed to get heat parameters for node {}  {}", parentType.getName(), parentId);
-								return Either.right(heatParametersStatus);
-							}
-							if (!heatParams.isEmpty()) {
-								artifactDefinition.setListHeatParameters(heatParams);
-							}
-							artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
-							log.debug("Artifact was added to list {}", artifact.getUniqueId());
-						}
-					}
-				}
-			}
-			result = Either.left(artifactMap);
-			return result;
-		} finally {
-			if (inTransaction == false) {
-				if (result == null || result.isRight()) {
-					this.titanGenericDao.rollback();
-				} else {
-					this.titanGenericDao.commit();
-				}
+                            ArtifactDefinition artifactDefinition = new ArtifactDefinition(artifact.getArtifactDataDefinition());
+                            Iterator<Edge> edgesGeneratedFrom = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty());
+                            if (edgesGeneratedFrom != null && edgesGeneratedFrom.hasNext()) {
+                                TitanVertex inVertex = (TitanVertex) edgesGeneratedFrom.next().inVertex();
+                                String artifactIdGeneratedFrom = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
+                                artifactDefinition.setGeneratedFromId(artifactIdGeneratedFrom);
+                            }
+                            List<HeatParameterDefinition> heatParams = new ArrayList<>();
+                            StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefinition.getUniqueId(), heatParams);
+                            if (!heatParametersStatus.equals(StorageOperationStatus.OK)) {
+                                log.debug("failed to get heat parameters for node {}  {}", parentType.getName(), parentId);
+                                return Either.right(heatParametersStatus);
+                            }
+                            if (!heatParams.isEmpty()) {
+                                artifactDefinition.setListHeatParameters(heatParams);
+                            }
+                            artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
+                            log.debug("Artifact was added to list {}", artifact.getUniqueId());
+                        }
+                    }
+                }
+            }
+            result = Either.left(artifactMap);
+            return result;
+        } finally {
+            if (!inTransaction) {
+                if (result == null || result.isRight()) {
+                    this.titanGenericDao.rollback();
+                } else {
+                    this.titanGenericDao.commit();
+                }
 
-			}
-		}
+            }
+        }
 
-	}
+    }
 
-	private void updateUUID(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion) {
-		if (oldVesrion == null || oldVesrion.isEmpty())
-			oldVesrion = "0";
+    private void updateUUID(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion) {
+        if (oldVesrion == null || oldVesrion.isEmpty())
+            oldVesrion = "0";
 
-		String currentChecksum = artifactData.getArtifactChecksum();
-		if (oldChecksum == null || oldChecksum.isEmpty()) {
-			if (currentChecksum != null) {
-				generateUUID(artifactData, oldVesrion);
-			}
-		} else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) {
-			generateUUID(artifactData, oldVesrion);
-		}
+        String currentChecksum = artifactData.getArtifactChecksum();
+        if (oldChecksum == null || oldChecksum.isEmpty()) {
+            if (currentChecksum != null) {
+                generateUUID(artifactData, oldVesrion);
+            }
+        } else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) {
+            generateUUID(artifactData, oldVesrion);
+        }
 
-	}
+    }
 
-	private void generateUUID(ArtifactDataDefinition artifactData, String oldVesrion) {
+    private void generateUUID(ArtifactDataDefinition artifactData, String oldVesrion) {
 
-		UUID uuid = UUID.randomUUID();
-		artifactData.setArtifactUUID(uuid.toString());
-		MDC.put("serviceInstanceID", uuid.toString());
-		updateVersionAndDate(artifactData, oldVesrion);
-	}
+        UUID uuid = UUID.randomUUID();
+        artifactData.setArtifactUUID(uuid.toString());
+        MDC.put("serviceInstanceID", uuid.toString());
+        updateVersionAndDate(artifactData, oldVesrion);
+    }
 
-	private void updateVersionAndDate(ArtifactDataDefinition artifactData, String oldVesrion) {
-		long time = System.currentTimeMillis();
-		artifactData.setPayloadUpdateDate(time);
-		int newVersion = new Integer(oldVesrion).intValue();
-		newVersion++;
-		artifactData.setArtifactVersion(String.valueOf(newVersion));
-	}
+    private void updateVersionAndDate(ArtifactDataDefinition artifactData, String oldVesrion) {
+        long time = System.currentTimeMillis();
+        artifactData.setPayloadUpdateDate(time);
+        int newVersion = new Integer(oldVesrion).intValue();
+        newVersion++;
+        artifactData.setArtifactVersion(String.valueOf(newVersion));
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.java
index d677a7e..758e465 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.java
@@ -20,185 +20,172 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.LinkedList;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import org.openecomp.sdc.be.config.Configuration;
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.cache.ComponentCache;
 import org.openecomp.sdc.be.model.cache.DaoInfo;
-import org.openecomp.sdc.be.model.cache.jobs.CheckAndUpdateJob;
-import org.openecomp.sdc.be.model.cache.jobs.DeleteJob;
-import org.openecomp.sdc.be.model.cache.jobs.Job;
-import org.openecomp.sdc.be.model.cache.jobs.OverrideJob;
-import org.openecomp.sdc.be.model.cache.jobs.StoreJob;
+import org.openecomp.sdc.be.model.cache.jobs.*;
 import org.openecomp.sdc.be.model.cache.workers.CacheWorker;
 import org.openecomp.sdc.be.model.cache.workers.IWorker;
 import org.openecomp.sdc.be.model.cache.workers.SyncWorker;
 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
-import org.openecomp.sdc.be.workers.Manager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.util.LinkedList;
+import java.util.concurrent.*;
 
 /**
  * Created by mlando on 9/5/2016. the class is responsible for handling all cache update operations asynchronously including sync between the graph and cache and on demand update requests
  */
 @Component("cacheManger-operation")
 public class CacheMangerOperation implements ICacheMangerOperation {
-	@Autowired
-	private ToscaOperationFacade toscaOperationFacade;
-	@Autowired
-	private TitanGenericDao titanGenericDao;
-	@Autowired
-	private ComponentCache componentCache;
+    @Autowired
+    private ToscaOperationFacade toscaOperationFacade;
+    @Autowired
+    private TitanGenericDao titanGenericDao;
+    @Autowired
+    private ComponentCache componentCache;
 
-	private static Logger log = LoggerFactory.getLogger(Manager.class.getName());
-	private LinkedBlockingQueue<Job> jobQueue = null;
-	private int waitOnShutDownInMinutes;
-	private ScheduledExecutorService syncExecutor;
-	private ExecutorService workerExecutor;
-	private LinkedList<IWorker> workerList = new LinkedList<>();
-	private DaoInfo daoInfo;
+    private static final Logger log = Logger.getLogger(CacheMangerOperation.class.getName());
+    private LinkedBlockingQueue<Job> jobQueue = null;
+    private int waitOnShutDownInMinutes;
+    private ScheduledExecutorService syncExecutor;
+    private ExecutorService workerExecutor;
+    private LinkedList<IWorker> workerList = new LinkedList<>();
+    private DaoInfo daoInfo;
 
-	/**
-	 * constructor
-	 */
-	public CacheMangerOperation() {
-	}
+    /**
+     * constructor
+     */
+    public CacheMangerOperation() {
+    }
 
-	/**
-	 * the method checks in the cache is enabled, if it is, it initializes all the workers according to the configuration values.
-	 */
-	@PostConstruct
-	public void init() {
+    /**
+     * the method checks in the cache is enabled, if it is, it initializes all the workers according to the configuration values.
+     */
+    @PostConstruct
+    public void init() {
 
-		daoInfo = new DaoInfo(toscaOperationFacade, componentCache);
+        daoInfo = new DaoInfo(toscaOperationFacade, componentCache);
 
-		Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL2Cache();
-		if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) {
-			Integer numberOfWorkers = applicationL2CacheConfig.getQueue().getNumberOfCacheWorkers();
-			this.waitOnShutDownInMinutes = applicationL2CacheConfig.getQueue().getWaitOnShutDownInMinutes();
-			jobQueue = new LinkedBlockingQueue<>();
-			log.info("L2 Cache is enabled inishilsing queue");
-			log.debug("initializing SyncWorker, creating {} workers");
-			ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Sync-Cache-Worker-%d").build();
-			this.syncExecutor = Executors.newSingleThreadScheduledExecutor(threadFactory);
-			log.debug("initializing workers, creating {} cacheWorkers", numberOfWorkers);
-			threadFactory = new ThreadFactoryBuilder().setNameFormat("Cache-Worker-%d").build();
-			String workerName = "Sync-Worker";
-			Integer syncWorkerExacutionIntrval = applicationL2CacheConfig.getQueue().getSyncIntervalInSecondes();
-			log.debug("starting Sync worker:{} with executions interval:{} ", workerName, syncWorkerExacutionIntrval);
-			SyncWorker syncWorker = new SyncWorker(workerName, this);
-			this.syncExecutor.scheduleAtFixedRate(syncWorker, 5 * 60, syncWorkerExacutionIntrval, TimeUnit.SECONDS);
-			this.workerExecutor = Executors.newFixedThreadPool(numberOfWorkers, threadFactory);
-			CacheWorker cacheWorker;
-			for (int i = 0; i < numberOfWorkers; i++) {
-				workerName = "Cache-Worker-" + i;
-				log.debug("starting Cache worker:{}", workerName);
-				cacheWorker = new CacheWorker(workerName, jobQueue);
-				this.workerExecutor.submit(cacheWorker);
-				this.workerList.add(cacheWorker);
-			}
-		} else {
-			log.info("L2 Cache is disabled");
-		}
-		log.info("L2 Cache has been initialized and the workers are running");
-	}
+        Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL2Cache();
+        if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) {
+            Integer numberOfWorkers = applicationL2CacheConfig.getQueue().getNumberOfCacheWorkers();
+            this.waitOnShutDownInMinutes = applicationL2CacheConfig.getQueue().getWaitOnShutDownInMinutes();
+            jobQueue = new LinkedBlockingQueue<>();
+            log.info("L2 Cache is enabled initializing queue");
+            log.debug("initializing SyncWorker, creating {} workers", numberOfWorkers);
+            ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Sync-Cache-Worker-%d").build();
+            this.syncExecutor = Executors.newSingleThreadScheduledExecutor(threadFactory);
+            log.debug("initializing workers, creating {} cacheWorkers", numberOfWorkers);
+            threadFactory = new ThreadFactoryBuilder().setNameFormat("Cache-Worker-%d").build();
+            String workerName = "Sync-Worker";
+            Integer syncWorkerExacutionIntrval = applicationL2CacheConfig.getQueue().getSyncIntervalInSecondes();
+            log.debug("starting Sync worker:{} with executions interval:{} ", workerName, syncWorkerExacutionIntrval);
+            SyncWorker syncWorker = new SyncWorker(workerName, this);
+            this.syncExecutor.scheduleAtFixedRate(syncWorker, 5 * 60, syncWorkerExacutionIntrval, TimeUnit.SECONDS);
+            this.workerExecutor = Executors.newFixedThreadPool(numberOfWorkers, threadFactory);
+            CacheWorker cacheWorker;
+            for (int i = 0; i < numberOfWorkers; i++) {
+                workerName = "Cache-Worker-" + i;
+                log.debug("starting Cache worker:{}", workerName);
+                cacheWorker = new CacheWorker(workerName, jobQueue);
+                this.workerExecutor.submit(cacheWorker);
+                this.workerList.add(cacheWorker);
+            }
+        } else {
+            log.info("L2 Cache is disabled");
+        }
+        log.info("L2 Cache has been initialized and the workers are running");
+    }
 
-	/**
-	 * the method creates a job to check it the given component is in the cach and if so is it valid if the value in the cache is not valid it will be updated.
-	 * 
-	 * @param componentId
-	 *            the uid of the component we want to update
-	 * @param timestamp
-	 *            the time of the component update
-	 * @param nodeTypeEnum
-	 *            the type of the component resource/service/product
-	 */
-	@Override
-	public void updateComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) {
-		Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL2Cache();
-		if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) {
-			this.jobQueue.add(new CheckAndUpdateJob(daoInfo, componentId, nodeTypeEnum, timestamp));
-		}
-	}
+    /**
+     * the method creates a job to check it the given component is in the cach and if so is it valid if the value in the cache is not valid it will be updated.
+     *
+     * @param componentId
+     *            the uid of the component we want to update
+     * @param timestamp
+     *            the time of the component update
+     * @param nodeTypeEnum
+     *            the type of the component resource/service/product
+     */
+    @Override
+    public void updateComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) {
+        Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL2Cache();
+        if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) {
+            this.jobQueue.add(new CheckAndUpdateJob(daoInfo, componentId, nodeTypeEnum, timestamp));
+        }
+    }
 
-	public void overideComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) {
-		Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL2Cache();
-		if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) {
-			this.jobQueue.add(new OverrideJob(daoInfo, componentId, nodeTypeEnum, timestamp));
-		}
-	}
+    public void overideComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) {
+        Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL2Cache();
+        if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) {
+            this.jobQueue.add(new OverrideJob(daoInfo, componentId, nodeTypeEnum, timestamp));
+        }
+    }
 
-	public void deleteComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) {
-		Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL2Cache();
-		if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) {
-			this.jobQueue.add(new DeleteJob(daoInfo, componentId, nodeTypeEnum, timestamp));
-		}
-	}
+    public void deleteComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) {
+        Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL2Cache();
+        if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) {
+            this.jobQueue.add(new DeleteJob(daoInfo, componentId, nodeTypeEnum, timestamp));
+        }
+    }
 
-	/**
-	 * the method stores the given component in the cache
-	 * 
-	 * @param component
-	 *            componet to store in cache
-	 * @param nodeTypeEnum
-	 *            the type of the component we want to store
-	 */
-	@Override
-	public void storeComponentInCache(org.openecomp.sdc.be.model.Component component, NodeTypeEnum nodeTypeEnum) {
-		Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL2Cache();
-		if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) {
-			this.jobQueue.add(new StoreJob(daoInfo, component, nodeTypeEnum));
-		}
-	}
+    /**
+     * the method stores the given component in the cache
+     *
+     * @param component
+     *            componet to store in cache
+     * @param nodeTypeEnum
+     *            the type of the component we want to store
+     */
+    @Override
+    public void storeComponentInCache(org.openecomp.sdc.be.model.Component component, NodeTypeEnum nodeTypeEnum) {
+        Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getApplicationL2Cache();
+        if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) {
+            this.jobQueue.add(new StoreJob(daoInfo, component, nodeTypeEnum));
+        }
+    }
 
-	/**
-	 * the method shutdown's all the worker's. the method has a pre set of how long it will wait for the workers to shutdown. the pre defined value is taken from the configuration.
-	 */
-	@PreDestroy
-	public void shutDown() {
-		workerExecutor.shutdown();
-		syncExecutor.shutdown();
-		this.workerList.forEach(e -> e.shutDown());
-		try {
-			if (!workerExecutor.awaitTermination(this.waitOnShutDownInMinutes, TimeUnit.MINUTES)) {
-				log.error("timer elapsed while waiting for Cache workers to finish, forcing a shutdown. ");
-			}
-			log.debug("all Cache workers finished");
-		} catch (InterruptedException e) {
-			log.error("failed while waiting for Cache worker", e);
-		}
-		try {
-			if (!workerExecutor.awaitTermination(1, TimeUnit.MINUTES)) {
-				log.error("timer elapsed while waiting for the Sync worker's to finish, forcing a shutdown. ");
-			}
-			log.debug("sync worker finished");
-		} catch (InterruptedException e) {
-			log.error("failed while waiting for sync worker", e);
-		}
-	}
+    /**
+     * the method shutdown's all the worker's. the method has a pre set of how long it will wait for the workers to shutdown. the pre defined value is taken from the configuration.
+     */
+    @PreDestroy
+    public void shutDown() {
+        workerExecutor.shutdown();
+        syncExecutor.shutdown();
+        this.workerList.forEach(IWorker::shutDown);
+        try {
+            if (!workerExecutor.awaitTermination(this.waitOnShutDownInMinutes, TimeUnit.MINUTES)) {
+                log.error("timer elapsed while waiting for Cache workers to finish, forcing a shutdown. ");
+            }
+            log.debug("all Cache workers finished");
+        } catch (InterruptedException e) {
+            log.error("failed while waiting for Cache worker", e);
+        }
+        try {
+            if (!workerExecutor.awaitTermination(1, TimeUnit.MINUTES)) {
+                log.error("timer elapsed while waiting for the Sync worker's to finish, forcing a shutdown. ");
+            }
+            log.debug("sync worker finished");
+        } catch (InterruptedException e) {
+            log.error("failed while waiting for sync worker", e);
+        }
+    }
 
-	public TitanGenericDao getTitanGenericDao() {
-		return titanGenericDao;
-	}
+    public TitanGenericDao getTitanGenericDao() {
+        return titanGenericDao;
+    }
 
-	public ComponentCache getComponentCache() {
-		return componentCache;
-	}
+    public ComponentCache getComponentCache() {
+        return componentCache;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java
index 175c695..7a17183 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java
@@ -20,114 +20,398 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.stream.Collectors;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Strings;
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
+import org.openecomp.sdc.be.dao.neo4j.GraphEdgePropertiesDictionary;
+import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.operations.api.ICapabilityOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.resources.data.CapabilityData;
 import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.openecomp.sdc.be.resources.data.PropertyData;
+import org.openecomp.sdc.be.resources.data.PropertyValueData;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
-import fj.data.Either;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static org.springframework.util.CollectionUtils.isEmpty;
 
 @Component("capability-operation")
-public class CapabilityOperation extends AbstractOperation implements ICapabilityOperation {
-
-	public CapabilityOperation() {
-		super();
-	}
-
-	private static Logger log = LoggerFactory.getLogger(CapabilityOperation.class.getName());
-
-	@Autowired
-	private PropertyOperation propertyOperation;
-
-	@Autowired
-	private TitanGenericDao titanGenericDao;
-
-	/**
-	 * FOR TEST ONLY
-	 * 
-	 * @param titanGenericDao
-	 */
-	public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
-		this.titanGenericDao = titanGenericDao;
-	}
+public class CapabilityOperation extends AbstractOperation {
 
 
-	@Override
-	public Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertyUniqueness(Map<String, PropertyDefinition> propertiesOfCapabilityType, List<PropertyDefinition> properties) {
-		Either<List<PropertyDefinition>, TitanOperationStatus> result = Either.left(properties);
+    private static final Logger log = Logger.getLogger(CapabilityOperation.class.getName());
 
-		for (PropertyDefinition property : properties) {
-			String propertyName = property.getName();
-			String propertyType = property.getType();
-			PropertyDefinition defaultProperty = null;
+    private final CapabilityTypeOperation capabilityTypeOperation;
+    private final PropertyOperation propertyOperation;
+    
 
-			if (propertiesOfCapabilityType.containsKey(propertyName)) {
-				defaultProperty = propertiesOfCapabilityType.get(propertyName);
-				if (propertyType != null && defaultProperty.getType() != null && !defaultProperty.getType().equals(propertyType)) {
-					log.error(" Property with name {} and different type already exists.", propertyName);
-					result = Either.right(TitanOperationStatus.PROPERTY_NAME_ALREADY_EXISTS);
-				} else {
-					property.setType(defaultProperty.getType());
-					String innerType = defaultProperty.getSchema() == null ? null : defaultProperty.getSchema().getProperty() == null ? null : defaultProperty.getSchema().getProperty().getType();
+    public CapabilityOperation(CapabilityTypeOperation capabilityTypeOperation, PropertyOperation propertyOperation) {
+        this.capabilityTypeOperation = capabilityTypeOperation;
+        this.propertyOperation = propertyOperation;
+    }
+    
+    
+    @VisibleForTesting
+    public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
+        this.titanGenericDao = titanGenericDao;
+    }
 
-					if (property.getSchema() != null && property.getSchema().getProperty() != null) {
-						property.getSchema().getProperty().setType(innerType);
-					}
-				}
-			}
-		}
-		return result;
-	}
+    public Either<CapabilityData, TitanOperationStatus> addCapabilityToGraph(String resourceId, CapabilityTypeData capTypeData, CapabilityDefinition capabilityDefinition) {
 
-	@Override
-	public Either<Map<String, PropertyDefinition>, TitanOperationStatus> getAllCapabilityTypePropertiesFromAllDerivedFrom(String firstParentType) {
-		Map<String, PropertyDefinition> allProperies = new HashMap<>();
-		return getCapabilityTypePropertiesFromDerivedFromRecursively(firstParentType, allProperies);
-	}
+        log.debug("#addCapabilityToGraph - capabilityDefinition={}", capabilityDefinition);
 
-	private Either<Map<String, PropertyDefinition>, TitanOperationStatus> getCapabilityTypePropertiesFromDerivedFromRecursively(String nextParentType, Map<String, PropertyDefinition> allProperies) {
-		TitanOperationStatus error;
-		Either<List<ImmutablePair<CapabilityTypeData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), nextParentType, GraphEdgeLabels.DERIVED_FROM,
-				NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
-		if (childrenNodes.isRight()) {
-			if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) {
-				error = childrenNodes.right().value();
-				log.debug("Couldn't fetch derived from node for capability type {}, error: {}", nextParentType, error);
-				return Either.right(error);
-			} else {
-				log.debug("Derived from node is not found for type {} - this is OK for root capability.");
-				return Either.left(allProperies);
-			}
-		} else {
+        String capUniqueId = UniqueIdBuilder.buildCapabilityUid(resourceId, capabilityDefinition.getName());
+        CapabilityData capabilityData = buildCapabilityData(capabilityDefinition, capUniqueId);
 
-			Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesOfCapabilityTypeRes = propertyOperation.findPropertiesOfNode(NodeTypeEnum.CapabilityType, nextParentType);
-			if (allPropertiesOfCapabilityTypeRes.isRight() && !allPropertiesOfCapabilityTypeRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
-				error = allPropertiesOfCapabilityTypeRes.right().value();
-				log.error("Failed to retrieve properties for capability type {} from graph. status is {}", nextParentType, error);
-				return Either.right(error);
-			} else if (allPropertiesOfCapabilityTypeRes.isLeft()) {
-				if (allProperies.isEmpty()) {
-					allProperies.putAll(allPropertiesOfCapabilityTypeRes.left().value());
-				} else {
-					allProperies.putAll(allPropertiesOfCapabilityTypeRes.left().value().entrySet().stream().filter(e -> !allProperies.containsKey(e.getKey())).collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
-				}
-			}
-			return getCapabilityTypePropertiesFromDerivedFromRecursively(childrenNodes.left().value().get(0).getLeft().getUniqueId(), allProperies);
-		}
-	}
+        log.debug("addCapabilityToGraph - Before adding capability to graph. capabilityTypeData = {}", capabilityData);
+        Either<CapabilityData, TitanOperationStatus> createCapResult = titanGenericDao.createNode(capabilityData, CapabilityData.class);
+        log.debug("addCapabilityToGraph - After adding capability to graph. status is = {}", createCapResult);
+
+        if (createCapResult.isRight()) {
+            TitanOperationStatus operationStatus = createCapResult.right().value();
+            log.error("addCapabilityToGraph - Failed to add capability of type {} to graph. status is {}", capabilityDefinition.getType(), operationStatus);
+            return createCapResult;
+        }
+        
+        createCapResult = connectToCapabilityType(capabilityData, capTypeData)
+                                .left()
+                                .bind(res -> createCapabilityProperties(capabilityData, capTypeData))
+                                .left()
+                                .map(res -> capabilityData);
+        
+        return createCapResult;
+    }
+    
+    private Either<GraphRelation, TitanOperationStatus> connectToCapabilityType(CapabilityData capabilityData, CapabilityTypeData capabilityTypeData) {
+        
+        Map<String, Object> properties = new HashMap<>();
+
+        String capabilityName = capabilityData.getCapabilityDataDefinition().getName();
+        properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), capabilityName);
+        
+        return titanGenericDao.createRelation(capabilityData, capabilityTypeData, GraphEdgeLabels.CAPABILITY_IMPL, properties);
+
+    }
+    
+
+    /**
+     * @param capabilites
+     * @return
+     */
+    public Either<List<CapabilityDefinition>, TitanOperationStatus> getCapabilitiesWithProps(List<ImmutablePair<CapabilityData, GraphEdge>> capabilites) {
+        List<Either<CapabilityDefinition, TitanOperationStatus>> listFilledCapabilitiesResults = capabilites.stream()
+                                                        .map(ImmutablePair::getLeft)
+                                                        .map(this::toCapabilityDefinitionWithProps)
+                                                        .collect(Collectors.toList());
+        
+        Optional<TitanOperationStatus> status = listFilledCapabilitiesResults.stream().filter(Either::isRight)
+                                                               .map(res -> res.right().value())
+                                                               .findFirst();
+        
+        if (status.isPresent()) {
+            return Either.right(status.get());
+        }
+        
+        List<CapabilityDefinition> listCapabilities = listFilledCapabilitiesResults.stream()
+                                                                                    .map(res -> res.left().value())
+                                                                                    .collect(Collectors.toList());
+        
+        return Either.left(listCapabilities);
+    }
+    
+    private Either<CapabilityDefinition, TitanOperationStatus> toCapabilityDefinitionWithProps(CapabilityData capabilityData) {
+        CapabilityDefinition capabilityDefinition = new CapabilityDefinition(capabilityData.getCapabilityDataDefinition());
+        return getCapabilityProperties(capabilityDefinition.getUniqueId(), capabilityDefinition.getType())
+                    .left()
+                    .map(props -> {
+                        capabilityDefinition.setProperties(props); 
+                        return capabilityDefinition;
+                    });
+    }
+    
+        
+    /**
+     * get all properties of the capability.
+     *
+     * the property definition is taken from the capability type.
+     *
+     * @param capabilityUid
+     * @return
+     */
+    private Either<List<ComponentInstanceProperty>, TitanOperationStatus> getCapabilityProperties(String capabilityUid, String capabilityType) {
+        Either<CapabilityTypeDefinition, TitanOperationStatus> capabilityTypeRes = capabilityTypeOperation.getCapabilityTypeByType(capabilityType);
+
+        if (capabilityTypeRes.isRight()) {
+            TitanOperationStatus status = capabilityTypeRes.right().value();
+            return Either.right(status);
+        }
+
+        CapabilityTypeDefinition capabilityTypeDefinition = capabilityTypeRes.left().value();
+
+        Either<Map<String, PropertyDefinition>, TitanOperationStatus> typesPropsRes = getPropertiesOfCapabilityTypeAndAcestors(capabilityTypeDefinition);
+        if (typesPropsRes.isRight()) {
+            TitanOperationStatus status = typesPropsRes.right().value();
+            return Either.right(status);
+        }
+        
+        Map<String, PropertyDefinition> capabilityTypeProperties = typesPropsRes.left().value();
+
+        if (isEmpty(capabilityTypeProperties)) {
+            return Either.right(TitanOperationStatus.OK);
+        }
+
+        Map<String, PropertyDefinition> uidToPropDefMap = capabilityTypeProperties.values().stream()
+                                                            .collect(Collectors.toMap(PropertyDefinition::getUniqueId, Function.identity()));
+
+        // Find all properties values on the capability
+        Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> propertyValNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capabilityUid, GraphEdgeLabels.PROPERTY_VALUE,
+                NodeTypeEnum.PropertyValue, PropertyValueData.class);
+
+        if (propertyValNodes.isRight()) {
+            return onLoadPropValuesFailure(propertyValNodes.right().value(), capabilityTypeProperties);
+        }
+
+        List<ImmutablePair<PropertyValueData, GraphEdge>> propValsRelationPairs = propertyValNodes.left().value();
+        if (isEmpty(propValsRelationPairs)) {
+            return Either.right(TitanOperationStatus.OK);
+        }
+
+        List<ComponentInstanceProperty> capabilityProperties = new ArrayList<>();
+
+        for (ImmutablePair<PropertyValueData, GraphEdge> propValRelPair : propValsRelationPairs) {
+
+            PropertyValueData propertyValueData = propValRelPair.getLeft();
+            Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueData.getUniqueId(), GraphEdgeLabels.PROPERTY_IMPL,
+                    NodeTypeEnum.Property, PropertyData.class);
+            if (propertyDefRes.isRight()) {
+                TitanOperationStatus status = propertyDefRes.right().value();
+                if (status == TitanOperationStatus.NOT_FOUND) {
+                    status = TitanOperationStatus.INVALID_ID;
+                }
+                return Either.right(status);
+            }
+
+            ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value();
+            PropertyData propertyData = propertyDefPair.left;
+            String propertyUniqueId = propertyData.getPropertyDataDefinition().getUniqueId();
+
+            PropertyDefinition propertyDefinition = uidToPropDefMap.get(propertyUniqueId);
+            ComponentInstanceProperty capabilityProperty = new ComponentInstanceProperty(propertyDefinition, propertyValueData.getValue(), propertyValueData.getUniqueId());
+
+            capabilityProperties.add(capabilityProperty);
+        }
+        
+        Set<String> processedProps = buildProcessedPropsSet(capabilityProperties);
+
+        // Find all properties which does not have property value on the group.
+        List<ComponentInstanceProperty> leftProps = filterCapabilityTypesProps(capabilityTypeProperties, processedProps);
+        if (leftProps != null) {
+            capabilityProperties.addAll(leftProps);
+        }
+
+        return Either.left(capabilityProperties);
+    }
+
+
+    /**
+     * @param capabilityProperties
+     * @return
+     */
+    private Set<String> buildProcessedPropsSet(List<ComponentInstanceProperty> capabilityProperties) {
+        return capabilityProperties.stream()
+                                    .map(ComponentInstanceProperty::getName)
+                                    .collect(Collectors.toSet());
+    }
+    
+    private Either<List<ComponentInstanceProperty>, TitanOperationStatus> onLoadPropValuesFailure(TitanOperationStatus status, Map<String, PropertyDefinition> capabilityTypeProperties) {
+        if (status == TitanOperationStatus.NOT_FOUND) {
+            return Either.left(buildPropsFromCapabilityTypeProps(capabilityTypeProperties));
+        } else {
+            return Either.right(status);
+        }
+    }
+
+
+    /**
+     * @param capabilityTypeProperties
+     * @return
+     */
+    private List<ComponentInstanceProperty> buildPropsFromCapabilityTypeProps(Map<String, PropertyDefinition> capabilityTypeProperties) {
+        return capabilityTypeProperties.values().stream()
+                                                    .map(p -> new ComponentInstanceProperty(p, p.getDefaultValue(), null))
+                                                    .collect(Collectors.toList());
+    }
+
+
+    /**
+     * @param capabilityTypeRes
+     * @param capabilityTypeDefinition
+     * @return
+     */
+    private Either<Map<String, PropertyDefinition>, TitanOperationStatus> getPropertiesOfCapabilityTypeAndAcestors(CapabilityTypeDefinition capabilityTypeDefinition) {
+        // Get the properties on the group type of this capability
+        Map<String, PropertyDefinition> capabilityTypeProperties = capabilityTypeDefinition.getProperties();
+        
+        String derivedFrom = capabilityTypeDefinition.getDerivedFrom();
+        if (!Strings.isNullOrEmpty(derivedFrom)) {
+            Either<Map<String, PropertyDefinition>, TitanOperationStatus> parentPropsRes = capabilityTypeOperation.getAllCapabilityTypePropertiesFromAllDerivedFrom(derivedFrom);
+            if(parentPropsRes.isRight()) {
+                TitanOperationStatus status = parentPropsRes.right().value();
+                return Either.right(status);
+            }
+            if (capabilityTypeProperties != null) {
+                capabilityTypeProperties.putAll(parentPropsRes.left().value());
+            } else {
+                capabilityTypeProperties = parentPropsRes.left().value();
+            }
+        }
+        
+        return Either.left(capabilityTypeProperties);
+    }
+    
+    
+    /**
+     * Create all property values of the capability and their 
+     * relations to relevant properties of the capability type.
+     *
+     * @param capabilityDefintion
+     * @param capabilityTypeData
+     * @return
+     */
+    private Either<List<ComponentInstanceProperty>, TitanOperationStatus> createCapabilityProperties(CapabilityData capabilityData,
+                                                                                                     CapabilityTypeData capabilityTypeData) {
+
+        CapabilityDefinition capabilityDefintion = (CapabilityDefinition)capabilityData.getCapabilityDataDefinition();
+        CapabilityTypeDefinition capabilityTypeDefinition = (CapabilityTypeDefinition)capabilityTypeData.getCapabilityTypeDataDefinition();
+
+        Either<Map<String, PropertyDefinition>, TitanOperationStatus> typesPropsRes = getPropertiesOfCapabilityTypeAndAcestors(capabilityTypeDefinition);
+        if (typesPropsRes.isRight()) {
+            TitanOperationStatus status = typesPropsRes.right().value();
+            return Either.right(status);
+        }
+        
+        Map<String, PropertyDefinition> capabilityTypeProperties = typesPropsRes.left().value();
+        
+        if (isEmpty(capabilityTypeProperties) && !isEmpty(capabilityDefintion.getProperties())) {
+            log.debug("#createCapabilityProperties - It's not valid if group capability has properties while corresponding capability type doesn't.");
+            return Either.right(TitanOperationStatus.MATCH_NOT_FOUND);
+        }
+
+        Optional<TitanOperationStatus> error = capabilityDefintion.getProperties().stream()
+                             .map(property -> createPropertyValue(property, capabilityData, capabilityTypeProperties.get(property.getName())))
+                             .filter(Either::isRight)
+                             .map(result -> result.right().value())
+                             .findFirst();
+        if (error.isPresent()) {
+            return Either.right(error.get());
+        }
+
+        return Either.left(capabilityDefintion.getProperties());
+    }
+
+
+    /**
+     * @param capabilityTypeProperties
+     * @param excludePropsWithUniqueIds
+     * @return
+     */
+    private List<ComponentInstanceProperty> filterCapabilityTypesProps(Map<String, PropertyDefinition> capabilityTypeProperties, 
+                                                                   Set<String> excludePropsWithNames) {
+        return capabilityTypeProperties.values().stream()
+                .filter(p -> !excludePropsWithNames.contains(p.getName()))
+                .map(p -> new ComponentInstanceProperty(p, p.getDefaultValue(), null))
+                .collect(Collectors.toList());
+    }
+
+    private  Either<PropertyValueData, TitanOperationStatus> createPropertyValue(ComponentInstanceProperty capabilityProperty, 
+                                                                              CapabilityData capabilityData,
+                                                                              PropertyDefinition capTypePropertyDefinition) {
+        if (capTypePropertyDefinition == null) {
+            return Either.right(TitanOperationStatus.MATCH_NOT_FOUND);
+        }
+        
+        CapabilityDefinition capabilityDefintion = (CapabilityDefinition)capabilityData.getCapabilityDataDefinition();
+        
+        Either<Integer, StorageOperationStatus> indexRes = 
+                propertyOperation.increaseAndGetObjInstancePropertyCounter(capabilityDefintion.getUniqueId(), NodeTypeEnum.Capability);
+        String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid(capabilityDefintion.getUniqueId(), indexRes.left().value() );
+        PropertyValueData propertyValueData = new PropertyValueData();
+        propertyValueData.setUniqueId(uniqueId);
+        propertyValueData.setValue(capabilityProperty.getValue());
+        Either<PropertyValueData, TitanOperationStatus> propResult = titanGenericDao.createNode(propertyValueData, PropertyValueData.class);
+        // It's not accepted if Capability Type doesn't have suitable property
+        propResult = propResult.left()
+                .bind(propValueData -> connectToProperty(propValueData, capTypePropertyDefinition))
+                .left()
+                .bind(graphRelation -> connectCapability(propertyValueData, capTypePropertyDefinition.getName(), capabilityData))
+                .left()
+                .map(graphRelation -> propertyValueData);
+        
+        propResult.left()
+                    .foreachDoEffect(propValueData -> capabilityProperty.setUniqueId(uniqueId));
+        
+        return propResult;
+    }
+    
+    private Either<GraphRelation, TitanOperationStatus> connectCapability(PropertyValueData propValueData, String name, CapabilityData capabilityData) {
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), name);
+
+        return titanGenericDao.createRelation(capabilityData, propValueData, GraphEdgeLabels.PROPERTY_VALUE, properties);
+    }
+    
+    private Either<GraphRelation, TitanOperationStatus> connectToProperty(PropertyValueData propValueData, PropertyDefinition propertyDefinition) {
+        Either<PropertyData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), 
+                                                                            propertyDefinition.getUniqueId(), PropertyData.class);
+
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), propertyDefinition.getName());
+        
+        return dataTypesRes.left()
+                           .bind(propertyData -> titanGenericDao.createRelation(propValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, properties));
+    }
+    
+
+    private CapabilityData buildCapabilityData(CapabilityDefinition capabilityDefinition, String ctUniqueId) {
+
+        CapabilityData capabilityData = new CapabilityData(capabilityDefinition);
+
+        capabilityData.setUniqueId(ctUniqueId);
+        Long creationDate = capabilityData.getCreationTime();
+        if (creationDate == null) {
+            creationDate = System.currentTimeMillis();
+        }
+        capabilityData.setCreationTime(creationDate);
+        capabilityData.setModificationTime(creationDate);
+        return capabilityData;
+    }
+
+
+    public StorageOperationStatus deleteCapability(CapabilityDefinition capabilityDef) {
+        
+        return titanGenericDao.deleteChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), capabilityDef.getUniqueId(), GraphEdgeLabels.PROPERTY_VALUE,
+                                                    NodeTypeEnum.PropertyValue, PropertyValueData.class)
+                 .left()
+                 .bind(props -> titanGenericDao.deleteNode(new CapabilityData(capabilityDef), CapabilityData.class))
+                 .right()
+                 .map(DaoStatusConverter::convertTitanStatusToStorageStatus)
+                 .right()
+                 .on(capData -> StorageOperationStatus.OK);
+    }
+    
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java
index 9b31c71..97f3e80 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java
@@ -20,379 +20,401 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
+import fj.data.Either;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
-import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.operations.api.ICapabilityOperation;
+import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
 import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.api.TypeOperations;
 import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
 import org.openecomp.sdc.be.resources.data.PropertyData;
-import org.openecomp.sdc.be.resources.data.UniqueIdData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import fj.data.Either;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 @Component("capability-type-operation")
 public class CapabilityTypeOperation extends AbstractOperation implements ICapabilityTypeOperation {
-	@Autowired
-	private PropertyOperation propertyOperation;
-	@Autowired
-	private ICapabilityOperation capabilityOperation;
+    @Autowired
+    private PropertyOperation propertyOperation;
+    @Autowired
+    private DerivedFromOperation derivedFromOperation;
 
-	public CapabilityTypeOperation() {
-		super();
-	}
+    public CapabilityTypeOperation() {
+        super();
+    }
 
-	private static Logger log = LoggerFactory.getLogger(CapabilityTypeOperation.class.getName());
+    private static final Logger log = Logger.getLogger(CapabilityTypeOperation.class.getName());
 
-	/**
-	 * FOR TEST ONLY
-	 * 
-	 * @param titanGenericDao
-	 */
-	public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
-		this.titanGenericDao = titanGenericDao;
-	}
+    /**
+     * FOR TEST ONLY
+     *
+     * @param titanGenericDao
+     */
+    public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
+        this.titanGenericDao = titanGenericDao;
+    }
 
-	@Override
-	public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction) {
+    @Override
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction) {
 
-		Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
+        Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
 
-		try {
-			Either<CapabilityTypeDefinition, TitanOperationStatus> validationRes = validateUpdateProperties(capabilityTypeDefinition);
-			if (validationRes.isRight()) {
-				log.error("One or all properties of capability type {} not valid. status is {}", capabilityTypeDefinition, validationRes.right().value().name());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(validationRes.right().value()));
-				return result;
-			}
-			Either<CapabilityTypeData, TitanOperationStatus> eitherStatus = addCapabilityTypeToGraph(capabilityTypeDefinition);
+        try {
+            Either<CapabilityTypeDefinition, StorageOperationStatus> validationRes = validateUpdateProperties(capabilityTypeDefinition);
+            if (validationRes.isRight()) {
+                log.error("#addCapabilityType - One or all properties of capability type {} not valid. status is {}", capabilityTypeDefinition, validationRes.right().value());
+                return result;
+            }
+            
+            Either<CapabilityTypeData, StorageOperationStatus> eitherStatus = addCapabilityTypeToGraph(capabilityTypeDefinition);
 
-			if (eitherStatus.isRight()) {
-				log.error("Failed to add capability {} to Graph. status is {}", capabilityTypeDefinition, eitherStatus.right().value().name());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
-				return result;
-			} else {
-				CapabilityTypeData capabilityTypeData = eitherStatus.left().value();
+            result = eitherStatus.left()
+                        .map(CapabilityTypeData::getUniqueId)
+                        .left()
+                        .bind(uniqueId -> getCapabilityType(uniqueId, inTransaction));
+            
+            if(result.isLeft()) {
+                log.debug("#addCapabilityType - The returned CapabilityTypeDefinition is {}", result.left().value());
+            }
+            
+            return result;
+        }
 
-				CapabilityTypeDefinition capabilityTypeDefResult = convertCTDataToCTDefinition(capabilityTypeData);
-				log.debug("The returned CapabilityTypeDefinition is {}", capabilityTypeDefResult);
-				result = Either.left(capabilityTypeDefResult);
-				return result;
-			}
-		}
+        finally {
+            if (!inTransaction) {
+                if (result == null || result.isRight()) {
+                    log.error("#addCapabilityType - Going to execute rollback on graph.");
+                    titanGenericDao.rollback();
+                } else {
+                    log.debug("#addCapabilityType - Going to execute commit on graph.");
+                    titanGenericDao.commit();
+                }
+            }
+        }
 
-		finally {
-			if (false == inTransaction) {
-				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
-					titanGenericDao.rollback();
-				} else {
-					log.debug("Going to execute commit on graph.");
-					titanGenericDao.commit();
-				}
-			}
-		}
+    }
+    
+    public Either<Map<String, PropertyDefinition>, TitanOperationStatus> getAllCapabilityTypePropertiesFromAllDerivedFrom(String firstParentType) {
+        return propertyOperation.getAllTypePropertiesFromAllDerivedFrom(firstParentType, NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
+    }
 
-	}
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> validateUpdateProperties(CapabilityTypeDefinition capabilityTypeDefinition) {
+        TitanOperationStatus error = null;
+        if (MapUtils.isNotEmpty(capabilityTypeDefinition.getProperties()) && capabilityTypeDefinition.getDerivedFrom() != null) {
+            Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesRes = 
+                                        getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeDefinition.getDerivedFrom());
+            if (allPropertiesRes.isRight() && !allPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
+                error = allPropertiesRes.right().value();
+                log.debug("Couldn't fetch derived from property nodes for capability type {}, error: {}", capabilityTypeDefinition.getType(), error);
+            }
+            if (error == null && !allPropertiesRes.left().value().isEmpty()) {
+                Map<String, PropertyDefinition> derivedFromProperties = allPropertiesRes.left().value();
+                capabilityTypeDefinition.getProperties().entrySet().stream().filter(e -> derivedFromProperties.containsKey(e.getKey()) && e.getValue().getType() == null)
+                        .forEach(e -> e.getValue().setType(derivedFromProperties.get(e.getKey()).getType()));
 
-	private Either<CapabilityTypeDefinition, TitanOperationStatus> validateUpdateProperties(CapabilityTypeDefinition capabilityTypeDefinition) {
-		TitanOperationStatus error = null;
-		if (capabilityTypeDefinition.getProperties() != null && !capabilityTypeDefinition.getProperties().isEmpty() && capabilityTypeDefinition.getDerivedFrom() != null) {
-			Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesRes = capabilityOperation.getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeDefinition.getDerivedFrom());
-			if (allPropertiesRes.isRight() && !allPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
-				error = allPropertiesRes.right().value();
-				log.debug("Couldn't fetch derived from property nodes for capability type {}, error: {}", capabilityTypeDefinition.getType(), error);
-			}
-			if (error == null && !allPropertiesRes.left().value().isEmpty()) {
-				Map<String, PropertyDefinition> derivedFromProperties = allPropertiesRes.left().value();
-				capabilityTypeDefinition.getProperties().entrySet().stream().filter(e -> derivedFromProperties.containsKey(e.getKey()) && e.getValue().getType() == null)
-						.forEach(e -> e.getValue().setType(derivedFromProperties.get(e.getKey()).getType()));
+                List<PropertyDefinition> properties = capabilityTypeDefinition.getProperties().values().stream().collect(Collectors.toList());
+                Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertiesRes = propertyOperation.validatePropertiesUniqueness(allPropertiesRes.left().value(),
+                        properties);
+                if (validatePropertiesRes.isRight()) {
+                    error = validatePropertiesRes.right().value();
+                }
+            }
+        }
+        if (error == null) {
+            return Either.left(capabilityTypeDefinition);
+        }
+        return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
+    }
+    
 
-				Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertiesRes = capabilityOperation.validatePropertyUniqueness(allPropertiesRes.left().value(),
-						capabilityTypeDefinition.getProperties().values().stream().collect(Collectors.toList()));
-				if (validatePropertiesRes.isRight()) {
-					error = validatePropertiesRes.right().value();
-				}
-			}
-		}
-		if (error == null) {
-			return Either.left(capabilityTypeDefinition);
-		}
-		return Either.right(error);
-	}
+    /**
+     *
+     * convert between graph Node object to Java object
+     *
+     * @param capabilityTypeData
+     * @return
+     */
+    protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) {
+        log.debug("The object returned after create capability is {}", capabilityTypeData);
 
-	/**
-	 * 
-	 * convert between graph Node object to Java object
-	 * 
-	 * @param capabilityTypeData
-	 * @return
-	 */
-	protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) {
-		log.debug("The object returned after create capability is {}", capabilityTypeData);
+        return new CapabilityTypeDefinition(capabilityTypeData.getCapabilityTypeDataDefinition());
+    }
 
-		CapabilityTypeDefinition capabilityTypeDefResult = new CapabilityTypeDefinition(capabilityTypeData.getCapabilityTypeDataDefinition());
+    /**
+     *
+     * Add capability type to graph.
+     *
+     * 1. Add capability type node
+     *
+     * 2. Add edge between the former node to its parent(if exists)
+     *
+     * 3. Add property node and associate it to the node created at #1. (per property & if exists)
+     *
+     * @param capabilityTypeDefinition
+     * @return
+     */
+    private Either<CapabilityTypeData, StorageOperationStatus> addCapabilityTypeToGraph(CapabilityTypeDefinition capabilityTypeDefinition) {
 
-		return capabilityTypeDefResult;
-	}
+        log.debug("Got capability type {}", capabilityTypeDefinition);
 
-	/**
-	 * 
-	 * Add capability type to graph.
-	 * 
-	 * 1. Add capability type node
-	 * 
-	 * 2. Add edge between the former node to its parent(if exists)
-	 * 
-	 * 3. Add property node and associate it to the node created at #1. (per property & if exists)
-	 * 
-	 * @param capabilityTypeDefinition
-	 * @return
-	 */
-	private Either<CapabilityTypeData, TitanOperationStatus> addCapabilityTypeToGraph(CapabilityTypeDefinition capabilityTypeDefinition) {
+        String ctUniqueId = UniqueIdBuilder.buildCapabilityTypeUid(capabilityTypeDefinition.getType());
+        CapabilityTypeData capabilityTypeData = buildCapabilityTypeData(capabilityTypeDefinition, ctUniqueId);
 
-		log.debug("Got capability type {}", capabilityTypeDefinition);
+        log.debug("Before adding capability type to graph. capabilityTypeData = {}", capabilityTypeData);
+        Either<CapabilityTypeData, TitanOperationStatus> createCTResult = titanGenericDao.createNode(capabilityTypeData, CapabilityTypeData.class);
+        log.debug("After adding capability type to graph. status is = {}", createCTResult);
 
-		String ctUniqueId = UniqueIdBuilder.buildCapabilityTypeUid(capabilityTypeDefinition.getType());
-		// capabilityTypeDefinition.setUniqueId(ctUniqueId);
+        if (createCTResult.isRight()) {
+            TitanOperationStatus operationStatus = createCTResult.right().value();
+            log.error("Failed to capability type {} to graph. status is {}", capabilityTypeDefinition.getType(), operationStatus);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
+        }
 
-		CapabilityTypeData capabilityTypeData = buildCapabilityTypeData(capabilityTypeDefinition, ctUniqueId);
+        CapabilityTypeData resultCTD = createCTResult.left().value();
+        Map<String, PropertyDefinition> propertiesMap = capabilityTypeDefinition.getProperties();
+        Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToCapablityType = propertyOperation.addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.CapabilityType, propertiesMap);
+        if (addPropertiesToCapablityType.isRight()) {
+            log.error("Failed add properties {} to capability {}", propertiesMap, capabilityTypeDefinition.getType());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesToCapablityType.right().value()));
+        }
 
-		log.debug("Before adding capability type to graph. capabilityTypeData = {}", capabilityTypeData);
-		Either<CapabilityTypeData, TitanOperationStatus> createCTResult = titanGenericDao.createNode(capabilityTypeData, CapabilityTypeData.class);
-		log.debug("After adding capability type to graph. status is = {}", createCTResult);
+        return addDerivedFromRelation(capabilityTypeDefinition, ctUniqueId)
+                .left()
+                .map(updatedDerivedFrom -> createCTResult.left().value());
 
-		if (createCTResult.isRight()) {
-			TitanOperationStatus operationStatus = createCTResult.right().value();
-			log.error("Failed to capability type {} to graph. status is {}", capabilityTypeDefinition.getType(), operationStatus);
-			return Either.right(operationStatus);
-		}
 
-		CapabilityTypeData resultCTD = createCTResult.left().value();
-		Map<String, PropertyDefinition> propertiesMap = capabilityTypeDefinition.getProperties();
-		Collection<PropertyDefinition> properties = propertiesMap != null ? propertiesMap.values() : null;
-		Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToCapablityType = propertyOperation.addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.CapabilityType, propertiesMap);
-		if (addPropertiesToCapablityType.isRight()) {
-			log.error("Failed add properties {} to capability {}", propertiesMap, capabilityTypeDefinition.getType());
-			return Either.right(addPropertiesToCapablityType.right().value());
-		}
+    }
 
-		String derivedFrom = capabilityTypeDefinition.getDerivedFrom();
-		if (derivedFrom != null) {
-			log.debug("Before creating relation between capability type {} to its parent {}", ctUniqueId, derivedFrom);
-			UniqueIdData from = new UniqueIdData(NodeTypeEnum.CapabilityType, ctUniqueId);
-			UniqueIdData to = new UniqueIdData(NodeTypeEnum.CapabilityType, derivedFrom);
-			Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null);
-			log.debug("After create relation between capability type {} to its parent {}. status is {}", ctUniqueId, derivedFrom, createRelation);
-			if (createRelation.isRight()) {
-				return Either.right(createRelation.right().value());
-			}
-		}
+    private CapabilityTypeData buildCapabilityTypeData(CapabilityTypeDefinition capabilityTypeDefinition, String ctUniqueId) {
 
-		return Either.left(createCTResult.left().value());
+        CapabilityTypeData capabilityTypeData = new CapabilityTypeData(capabilityTypeDefinition);
 
-	}
+        capabilityTypeData.getCapabilityTypeDataDefinition().setUniqueId(ctUniqueId);
+        Long creationDate = capabilityTypeData.getCapabilityTypeDataDefinition().getCreationTime();
+        if (creationDate == null) {
+            creationDate = System.currentTimeMillis();
+        }
+        capabilityTypeData.getCapabilityTypeDataDefinition().setCreationTime(creationDate);
+        capabilityTypeData.getCapabilityTypeDataDefinition().setModificationTime(creationDate);
+        return capabilityTypeData;
+    }
 
-	private CapabilityTypeData buildCapabilityTypeData(CapabilityTypeDefinition capabilityTypeDefinition, String ctUniqueId) {
+    @Override
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, boolean inTransaction) {
 
-		CapabilityTypeData capabilityTypeData = new CapabilityTypeData(capabilityTypeDefinition);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
+        try {
 
-		capabilityTypeData.getCapabilityTypeDataDefinition().setUniqueId(ctUniqueId);
-		Long creationDate = capabilityTypeData.getCapabilityTypeDataDefinition().getCreationTime();
-		if (creationDate == null) {
-			creationDate = System.currentTimeMillis();
-		}
-		capabilityTypeData.getCapabilityTypeDataDefinition().setCreationTime(creationDate);
-		capabilityTypeData.getCapabilityTypeDataDefinition().setModificationTime(creationDate);
-		return capabilityTypeData;
-	}
+            Either<CapabilityTypeDefinition, TitanOperationStatus> ctResult = this.getCapabilityTypeByUid(uniqueId);
 
-	@Override
-	public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, boolean inTransaction) {
+            if (ctResult.isRight()) {
+                TitanOperationStatus status = ctResult.right().value();
+                if (status != TitanOperationStatus.NOT_FOUND) {
+                    log.error("Failed to retrieve information on capability type {}. status is {}", uniqueId, status);
+                }
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
+                return result;
+            }
 
-		Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
-		try {
+            result = Either.left(ctResult.left().value());
 
-			Either<CapabilityTypeDefinition, TitanOperationStatus> ctResult = this.getCapabilityTypeByUid(uniqueId);
+            return result;
+        } finally {
+            if (!inTransaction) {
+                log.debug("Going to execute commit on graph.");
+                titanGenericDao.commit();
+            }
+        }
+    }
 
-			if (ctResult.isRight()) {
-				TitanOperationStatus status = ctResult.right().value();
-				if (status != TitanOperationStatus.NOT_FOUND) {
-					log.error("Failed to retrieve information on capability type {}. status is {}", uniqueId, status);
-				}
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
-				return result;
-			}
 
-			result = Either.left(ctResult.left().value());
+    public Either<CapabilityTypeDefinition, TitanOperationStatus> getCapabilityTypeByType(String capabilityType) {
+        // Optimization: In case of Capability Type its unique ID is the same as type
+        return getCapabilityTypeByUid(capabilityType);
+    }
 
-			return result;
-		} finally {
-			if (false == inTransaction) {
-				log.debug("Going to execute commit on graph.");
-				titanGenericDao.commit();
-			}
-		}
-	}
-	
-	
-	public Either<CapabilityTypeData, TitanOperationStatus> getCapabilityTypeByType(String capabilityType) {
-		Either<CapabilityTypeData, TitanOperationStatus> capabilityTypesRes = titanGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), capabilityType, CapabilityTypeData.class);
+    /**
+     * Build Capability type object from graph by unique id
+     *
+     * @param uniqueId
+     * @return
+     */
+    public Either<CapabilityTypeDefinition, TitanOperationStatus> getCapabilityTypeByUid(String uniqueId) {
 
-		if (capabilityTypesRes.isRight()) {
-			TitanOperationStatus status = capabilityTypesRes.right().value();
-			log.debug("Capability type {} cannot be found in graph. status is {}", capabilityType, status);
-			
-			return Either.right(status);
-		}
+        Either<CapabilityTypeDefinition, TitanOperationStatus> result = null;
 
-		CapabilityTypeData ctData = capabilityTypesRes.left().value();
-		return Either.left(ctData);
-	}
+        Either<CapabilityTypeData, TitanOperationStatus> capabilityTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, CapabilityTypeData.class);
 
-	/**
-	 * Build Capability type object from graph by unique id
-	 * 
-	 * @param uniqueId
-	 * @return
-	 */
-	public Either<CapabilityTypeDefinition, TitanOperationStatus> getCapabilityTypeByUid(String uniqueId) {
+        if (capabilityTypesRes.isRight()) {
+            TitanOperationStatus status = capabilityTypesRes.right().value();
+            log.debug("Capability type {} cannot be found in graph. status is {}", uniqueId, status);
+            return Either.right(status);
+        }
 
-		Either<CapabilityTypeDefinition, TitanOperationStatus> result = null;
+        CapabilityTypeData ctData = capabilityTypesRes.left().value();
+        CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
 
-		Either<CapabilityTypeData, TitanOperationStatus> capabilityTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, CapabilityTypeData.class);
+        TitanOperationStatus propertiesStatus = fillProperties(uniqueId, capabilityTypeDefinition);
+        if (propertiesStatus != TitanOperationStatus.OK) {
+            log.error("Failed to fetch properties of capability type {}", uniqueId);
+            return Either.right(propertiesStatus);
+        }
 
-		if (capabilityTypesRes.isRight()) {
-			TitanOperationStatus status = capabilityTypesRes.right().value();
-			log.debug("Capability type {} cannot be found in graph. status is {}", uniqueId, status);
-			return Either.right(status);
-		}
+        Either<ImmutablePair<CapabilityTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, GraphEdgeLabels.DERIVED_FROM,
+                NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
+        log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
+        if (parentNode.isRight()) {
+            TitanOperationStatus titanOperationStatus = parentNode.right().value();
+            if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
+                log.error("Failed to find the parent capability of capability type {}. status is {}", uniqueId, titanOperationStatus);
+                result = Either.right(titanOperationStatus);
+                return result;
+            }
+        } else {
+            // derived from node was found
+            ImmutablePair<CapabilityTypeData, GraphEdge> immutablePair = parentNode.left().value();
+            CapabilityTypeData parentCT = immutablePair.getKey();
+            capabilityTypeDefinition.setDerivedFrom(parentCT.getCapabilityTypeDataDefinition().getType());
+        }
+        result = Either.left(capabilityTypeDefinition);
 
-		CapabilityTypeData ctData = capabilityTypesRes.left().value();
-		CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
+        return result;
+    }
 
-		TitanOperationStatus propertiesStatus = fillProperties(uniqueId, capabilityTypeDefinition);
-		if (propertiesStatus != TitanOperationStatus.OK) {
-			log.error("Failed to fetch properties of capability type {}", uniqueId);
-			return Either.right(propertiesStatus);
-		}
+    private TitanOperationStatus fillProperties(String uniqueId, CapabilityTypeDefinition capabilityTypeDefinition) {
 
-		Either<ImmutablePair<CapabilityTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, GraphEdgeLabels.DERIVED_FROM,
-				NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
-		log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
-		if (parentNode.isRight()) {
-			TitanOperationStatus titanOperationStatus = parentNode.right().value();
-			if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
-				log.error("Failed to find the parent capability of capability type {}. status is {}", uniqueId, titanOperationStatus);
-				result = Either.right(titanOperationStatus);
-				return result;
-			}
-		} else {
-			// derived from node was found
-			ImmutablePair<CapabilityTypeData, GraphEdge> immutablePair = parentNode.left().value();
-			CapabilityTypeData parentCT = immutablePair.getKey();
-			capabilityTypeDefinition.setDerivedFrom(parentCT.getCapabilityTypeDataDefinition().getType());
-		}
-		result = Either.left(capabilityTypeDefinition);
+        Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = propertyOperation.findPropertiesOfNode(NodeTypeEnum.CapabilityType, uniqueId);
+        if (findPropertiesOfNode.isRight()) {
+            TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
+            log.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
+            if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
+                return TitanOperationStatus.OK;
+            } else {
+                return titanOperationStatus;
+            }
+        } else {
+            Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
+            capabilityTypeDefinition.setProperties(properties);
+            return TitanOperationStatus.OK;
+        }
+    }
 
-		return result;
-	}
+    public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, String parentCandidateType) {
+        return derivedFromOperation.isTypeDerivedFrom(childCandidateType, parentCandidateType, null, NodeTypeEnum.CapabilityType, CapabilityTypeData.class, t -> t.getCapabilityTypeDataDefinition().getType());
+    }
+    
+    
+    @Override
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> updateCapabilityType(CapabilityTypeDefinition capabilityTypeDefNew, 
+                                                                                         CapabilityTypeDefinition capabilityTypeDefOld) {
+        log.debug("updating capability type {}", capabilityTypeDefNew.getType());
+        updateCapabilityTypeData(capabilityTypeDefNew, capabilityTypeDefOld);
+        return updateCapabilityTypeOnGraph(capabilityTypeDefNew, capabilityTypeDefOld);
+    }
+    
+    
+    private Either<CapabilityTypeDefinition, StorageOperationStatus> updateCapabilityTypeOnGraph(CapabilityTypeDefinition capabilityTypeDefinitionNew, CapabilityTypeDefinition capabilityTypeDefinitionOld) {
+        return titanGenericDao.updateNode(new CapabilityTypeData(capabilityTypeDefinitionNew), CapabilityTypeData.class)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus)
+                .left()
+                .bind(updatedNode -> updateProperties(capabilityTypeDefinitionNew.getUniqueId(), capabilityTypeDefinitionNew.getProperties()))
+                .left()
+                .bind(updatedProperties -> updateDerivedFrom(capabilityTypeDefinitionNew, capabilityTypeDefinitionOld.getDerivedFrom()))
+                .right()
+                .bind(result -> TypeOperations.mapOkStatus(result, null))
+                .left()
+                .map(updatedDerivedFrom -> capabilityTypeDefinitionNew);
+    }
 
-	private TitanOperationStatus fillProperties(String uniqueId, CapabilityTypeDefinition capabilityTypeDefinition) {
+    private Either<Map<String, PropertyData>, StorageOperationStatus> updateProperties(String capabilityTypeId, Map<String, PropertyDefinition> properties) {
+        log.debug("#updateCapabilityTypeProperties - updating properties for capability type with id {}", capabilityTypeId);
+        return propertyOperation.mergePropertiesAssociatedToNode(NodeTypeEnum.CapabilityType, capabilityTypeId, properties)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+    }
 
-		Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = propertyOperation.findPropertiesOfNode(NodeTypeEnum.CapabilityType, uniqueId);
-		if (findPropertiesOfNode.isRight()) {
-			TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
-			log.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
-			if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
-				return TitanOperationStatus.OK;
-			} else {
-				return titanOperationStatus;
-			}
-		} else {
-			Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
-			capabilityTypeDefinition.setProperties(properties);
-			return TitanOperationStatus.OK;
-		}
-	}
+    private Either<GraphRelation, StorageOperationStatus> updateDerivedFrom(CapabilityTypeDefinition updatedCapabilityType, String currDerivedFromCapabilityType) {
+        if( StringUtils.equals(updatedCapabilityType.getDerivedFrom(), currDerivedFromCapabilityType)) {
+            return Either.right(StorageOperationStatus.OK);
+        }
+        
+        StorageOperationStatus status = isLegalToReplaceParent(currDerivedFromCapabilityType, updatedCapabilityType.getDerivedFrom(), updatedCapabilityType.getType());
+        if ( status != StorageOperationStatus.OK) {
+            return Either.right(status);
+        }
+        
+        String capabilityTypeId = updatedCapabilityType.getUniqueId();
+        log.debug("#updateCapabilityTypeDerivedFrom - updating capability type derived from relation for capability type with id {}. old derived type {}. new derived type {}", capabilityTypeId, currDerivedFromCapabilityType, updatedCapabilityType.getDerivedFrom());
+        StorageOperationStatus deleteDerivedRelationStatus = deleteDerivedFromCapabilityType(capabilityTypeId, currDerivedFromCapabilityType);
+        if (deleteDerivedRelationStatus != StorageOperationStatus.OK) {
+            return Either.right(deleteDerivedRelationStatus);
+        }
+        return addDerivedFromRelation(updatedCapabilityType, capabilityTypeId);
+    }
+    
+    private StorageOperationStatus isLegalToReplaceParent(String oldTypeParent, String newTypeParent, String childType) {
+        return derivedFromOperation.isUpdateParentAllowed(oldTypeParent, newTypeParent, childType, NodeTypeEnum.CapabilityType, CapabilityTypeData.class, t -> t.getCapabilityTypeDataDefinition().getType());
+    }
 
-	public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, String parentCandidateType) {
-		Map<String, Object> propertiesToMatch = new HashMap<String, Object>();
-		propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childCandidateType);
-		Either<List<CapabilityTypeData>, TitanOperationStatus> getResponse = titanGenericDao.getByCriteria(NodeTypeEnum.CapabilityType, propertiesToMatch, CapabilityTypeData.class);
-		if (getResponse.isRight()) {
-			TitanOperationStatus titanOperationStatus = getResponse.right().value();
-			log.debug("Couldn't fetch capability type {}, error: {}", childCandidateType, titanOperationStatus);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus));
-		}
-		String childUniqueId = getResponse.left().value().get(0).getUniqueId();
-		Set<String> travelledTypes = new HashSet<>();
-		do {
-			travelledTypes.add(childUniqueId);
-			Either<List<ImmutablePair<CapabilityTypeData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childUniqueId, GraphEdgeLabels.DERIVED_FROM,
-					NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
-			if (childrenNodes.isRight()) {
-				if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) {
-					TitanOperationStatus titanOperationStatus = getResponse.right().value();
-					log.debug("Couldn't fetch derived from node for capability type {}, error: {}", childCandidateType, titanOperationStatus);
-					return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus));
-				} else {
-					log.debug("Derived from node is not found for type {} - this is OK for root capability.");
-					return Either.left(false);
-				}
-			}
-			String derivedFromUniqueId = childrenNodes.left().value().get(0).getLeft().getUniqueId();
-			if (derivedFromUniqueId.equals(parentCandidateType)) {
-				log.debug("Verified that capability type {} derives from capability type {}", childCandidateType, parentCandidateType);
-				return Either.left(true);
-			}
-			childUniqueId = derivedFromUniqueId;
-		} while (!travelledTypes.contains(childUniqueId));
-		// this stop condition should never be used, if we use it, we have an
-		// illegal cycle in graph - "derived from" hierarchy cannot be cycled.
-		// It's here just to avoid infinite loop in case we have such cycle.
-		log.error("Detected a cycle of \"derived from\" edges starting at capability type node {}", childUniqueId);
-		return Either.right(StorageOperationStatus.GENERAL_ERROR);
-	}
+    private Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(CapabilityTypeDefinition capabilityTypeDef, String ptUniqueId) {
+        String derivedFrom = capabilityTypeDef.getDerivedFrom();
+        if (derivedFrom == null) {
+            return Either.left(null);
+        }
+        log.debug("#addDerivedFromRelationBefore - adding derived from relation between capability type {} to its parent {}", capabilityTypeDef.getType(), derivedFrom);
+        return this.getCapabilityType(derivedFrom, true)
+                .left()
+                .bind(derivedFromCapabilityType -> derivedFromOperation.addDerivedFromRelation(ptUniqueId, derivedFromCapabilityType.getUniqueId(), NodeTypeEnum.CapabilityType));
+    }
 
-	/**
-	 * FOR TEST ONLY
-	 * 
-	 * @param propertyOperation
-	 */
-	public void setPropertyOperation(PropertyOperation propertyOperation) {
-		this.propertyOperation = propertyOperation;
-	}
+    private StorageOperationStatus deleteDerivedFromCapabilityType(String capabilityTypeId, String derivedFromType) {
+        if (derivedFromType == null) {
+            return StorageOperationStatus.OK;
+        }
+        log.debug("#deleteDerivedFromCapabilityType - deleting derivedFrom relation for capability type with id {} and its derived type {}", capabilityTypeId, derivedFromType);
+        return getCapabilityType(derivedFromType, true)
+                .either(derivedFromNode -> derivedFromOperation.removeDerivedFromRelation(capabilityTypeId, derivedFromNode.getUniqueId(), NodeTypeEnum.CapabilityType),
+                        err -> err);
+    }  
+    
+    private void updateCapabilityTypeData(CapabilityTypeDefinition updatedTypeDefinition, CapabilityTypeDefinition currTypeDefinition) {
+        updatedTypeDefinition.setUniqueId(currTypeDefinition.getUniqueId());
+        updatedTypeDefinition.setCreationTime(currTypeDefinition.getCreationTime());
+    }
 
-	@Override
-	public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition) {
 
-		return addCapabilityType(capabilityTypeDefinition, false);
-	}
+    /**
+     * FOR TEST ONLY
+     *
+     * @param propertyOperation
+     */
+    public void setPropertyOperation(PropertyOperation propertyOperation) {
+        this.propertyOperation = propertyOperation;
+    }
 
-	@Override
-	public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId) {
-		return getCapabilityType(uniqueId, false);
-	}
+    @Override
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition) {
 
+        return addCapabilityType(capabilityTypeDefinition, true);
+    }
+
+    @Override
+    public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId) {
+        return getCapabilityType(uniqueId, true);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CommonTypeOperations.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CommonTypeOperations.java
new file mode 100644
index 0000000..0189b61
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CommonTypeOperations.java
@@ -0,0 +1,84 @@
+package org.openecomp.sdc.be.model.operations.impl;
+
+import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
+import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
+import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static java.util.Collections.emptyList;
+
+@Component
+public class CommonTypeOperations {
+
+    private final TitanGenericDao titanGenericDao;
+    private final PropertyOperation propertyOperation;
+    private final OperationUtils operationUtils;
+
+    public CommonTypeOperations(TitanGenericDao titanGenericDao, PropertyOperation propertyOperation, OperationUtils operationUtils) {
+        this.titanGenericDao = titanGenericDao;
+        this.propertyOperation = propertyOperation;
+        this.operationUtils = operationUtils;
+    }
+
+    public <T extends GraphNode> void addType(T typeData, Class<T> clazz) {
+        titanGenericDao.createNode(typeData, clazz)
+            .left()
+            .on(operationUtils::onTitanOperationFailure);
+    }
+
+    public <T extends GraphNode> Optional<T> getType(String uniqueId, Class<T> clazz, NodeTypeEnum nodeType) {
+        T type = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, clazz)
+                .left()
+                .on(err -> null);
+        return Optional.ofNullable(type);
+    }
+
+    public <T extends GraphNode> Optional<T> getLatestType(String type, Class<T> clazz, NodeTypeEnum nodeType) {
+        Map<String, Object> mapCriteria = new HashMap<>();
+        mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type);
+        mapCriteria.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true);
+        return titanGenericDao.getByCriteria(nodeType, mapCriteria, clazz)
+                .left()
+                .on(err -> emptyList())
+                .stream()
+                .findFirst();
+    }
+
+    public void addProperties(String uniqueId, NodeTypeEnum nodeType, List<PropertyDefinition> properties) {
+        propertyOperation.addPropertiesToElementType(uniqueId, nodeType, properties)
+            .left()
+            .on(operationUtils::onTitanOperationFailure);
+    }
+
+    public void fillProperties(String uniqueId, NodeTypeEnum nodeType, Consumer<List<PropertyDefinition>> propertySetter) {
+        TitanOperationStatus status = propertyOperation.fillPropertiesList(uniqueId, nodeType, propertySetter);
+        if (status!=TitanOperationStatus.OK) {
+            operationUtils.onTitanOperationFailure(status);
+        }
+    }
+
+    /**
+     * Handle update of type without dervidedFrom attribute
+     */
+    public  <T extends GraphNode> void updateType(T typeData, List<PropertyDefinition> properties, Class<T> clazz, NodeTypeEnum nodeType) {
+        titanGenericDao.updateNode(typeData, clazz)
+                .left()
+                .on(operationUtils::onTitanOperationFailure);
+        Map<String, PropertyDefinition> newProperties = properties.stream()
+                .collect(Collectors.toMap(PropertyDefinition::getName, Function.identity()));
+        propertyOperation.mergePropertiesAssociatedToNode(nodeType, typeData.getUniqueId(), newProperties)
+                .left()
+                .on(operationUtils::onTitanOperationFailure);
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java
index e67f9a4..fb0674c 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java
@@ -20,11 +20,9 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.function.Supplier;
-
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
@@ -41,687 +39,667 @@
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceInput;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
 import org.openecomp.sdc.be.model.operations.api.IComponentInstanceOperation;
 import org.openecomp.sdc.be.model.operations.api.IInputsOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
-import org.openecomp.sdc.be.resources.data.AttributeData;
-import org.openecomp.sdc.be.resources.data.AttributeValueData;
-import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
-import org.openecomp.sdc.be.resources.data.InputValueData;
-import org.openecomp.sdc.be.resources.data.InputsData;
+import org.openecomp.sdc.be.resources.data.*;
 import org.openecomp.sdc.common.datastructure.Wrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.function.Supplier;
 
 @org.springframework.stereotype.Component("component-instance-operation")
 public class ComponentInstanceOperation extends AbstractOperation implements IComponentInstanceOperation {
 
-	public ComponentInstanceOperation() {
-		super();
-	}
+    public ComponentInstanceOperation() {
+        super();
+    }
 
-	private static Logger log = LoggerFactory.getLogger(ComponentInstanceOperation.class.getName());
+    private static final Logger log = Logger.getLogger(ComponentInstanceOperation.class.getName());
 
-	@Autowired
-	TitanGenericDao titanGenericDao;
+    @Autowired
+    PropertyOperation propertyOperation;
 
-	@Autowired
-	PropertyOperation propertyOperation;
+    @Autowired
+    private IInputsOperation inputOperation;
 
-	@Autowired
-	private IInputsOperation inputOperation;
+    @Autowired
+    private ApplicationDataTypeCache dataTypeCache;
 
-	@Autowired
-	private ApplicationDataTypeCache dataTypeCache;
+    /**
+     * FOR TEST ONLY
+     *
+     * @param titanGenericDao
+     */
+    public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
+        this.titanGenericDao = titanGenericDao;
+    }
 
-	/**
-	 * FOR TEST ONLY
-	 * 
-	 * @param titanGenericDao
-	 */
-	public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
-		this.titanGenericDao = titanGenericDao;
-	}
+    @Override
+    public Either<Integer, StorageOperationStatus> increaseAndGetResourceInstanceSpecificCounter(String resourceInstanceId, GraphPropertiesDictionary counterType, boolean inTransaction) {
 
-	@Override
-	public Either<Integer, StorageOperationStatus> increaseAndGetResourceInstanceSpecificCounter(String resourceInstanceId, GraphPropertiesDictionary counterType, boolean inTransaction) {
+        Either<Integer, StorageOperationStatus> result = null;
+        try {
 
-		Either<Integer, StorageOperationStatus> result = null;
-		try {
+            Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph();
+            if (graphResult.isRight()) {
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value()));
+                return result;
+            }
+            Either<TitanVertex, TitanOperationStatus> vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId);
+            if (vertexService.isRight()) {
+                log.debug("failed to fetch vertex of resource instance for id = {}", resourceInstanceId);
+                TitanOperationStatus status = vertexService.right().value();
+                if (status == TitanOperationStatus.NOT_FOUND) {
+                    status = TitanOperationStatus.INVALID_ID;
+                }
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value()));
+                return result;
+            }
+            Vertex vertex = vertexService.left().value();
 
-			Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph();
-			if (graphResult.isRight()) {
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value()));
-				return result;
-			}
-			Either<TitanVertex, TitanOperationStatus> vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId);
-			if (vertexService.isRight()) {
-				log.debug("failed to fetch vertex of resource instance for id = {}", resourceInstanceId);
-				TitanOperationStatus status = vertexService.right().value();
-				if (status == TitanOperationStatus.NOT_FOUND) {
-					status = TitanOperationStatus.INVALID_ID;
-				}
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value()));
-				return result;
-			}
-			Vertex vertex = vertexService.left().value();
+            VertexProperty<Object> vertexProperty = vertex.property(counterType.getProperty());
+            Integer counter = 0;
+            if (vertexProperty.isPresent()) {
+                if (vertexProperty.value() != null) {
+                    counter = (Integer) vertexProperty.value();
+                }
+            }
 
-			VertexProperty<Object> vertexProperty = vertex.property(counterType.getProperty());
-			Integer counter = 0;
-			if (vertexProperty.isPresent()) {
-				if (vertexProperty.value() != null) {
-					counter = (Integer) vertexProperty.value();
-				}
-			}
+            counter++;
+            vertex.property(counterType.getProperty(), counter);
 
-			counter++;
-			vertex.property(counterType.getProperty(), counter);
+            result = Either.left(counter);
+            return result;
 
-			result = Either.left(counter);
-			return result;
+        } finally {
+            if (!inTransaction) {
+                if (result == null || result.isRight()) {
+                    log.error("increaseAndGetResourceInstanceSpecificCounter operation : Going to execute rollback on graph.");
+                    titanGenericDao.rollback();
+                } else {
+                    log.debug("increaseAndGetResourceInstanceSpecificCounter operation : Going to execute commit on graph.");
+                    titanGenericDao.commit();
+                }
+            }
+        }
 
-		} finally {
-			if (false == inTransaction) {
-				if (result == null || result.isRight()) {
-					log.error("increaseAndGetResourceInstanceSpecificCounter operation : Going to execute rollback on graph.");
-					titanGenericDao.rollback();
-				} else {
-					log.debug("increaseAndGetResourceInstanceSpecificCounter operation : Going to execute commit on graph.");
-					titanGenericDao.commit();
-				}
-			}
-		}
+    }
 
-	}
+    private void connectAttValueDataToComponentInstanceData(Wrapper<TitanOperationStatus> errorWrapper, ComponentInstanceData compIns, AttributeValueData attValueData) {
 
-	private void connectAttValueDataToComponentInstanceData(Wrapper<TitanOperationStatus> errorWrapper, ComponentInstanceData compIns, AttributeValueData attValueData) {
+        Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(compIns, attValueData, GraphEdgeLabels.ATTRIBUTE_VALUE, null);
 
-		Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(compIns, attValueData, GraphEdgeLabels.ATTRIBUTE_VALUE, null);
+        if (createRelResult.isRight()) {
+            TitanOperationStatus operationStatus = createRelResult.right().value();
+            errorWrapper.setInnerElement(operationStatus);
+            BeEcompErrorManager.getInstance().logInternalFlowError("connectAttValueDataToComponentInstanceData",
+                    "Failed to associate resource instance " + compIns.getUniqueId() + " attribute value " + attValueData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR);
+        }
+    }
 
-		if (createRelResult.isRight()) {
-			TitanOperationStatus operationStatus = createRelResult.right().value();
-			errorWrapper.setInnerElement(operationStatus);
-			BeEcompErrorManager.getInstance().logInternalFlowError("connectAttValueDataToComponentInstanceData",
-					"Failed to associate resource instance " + compIns.getUniqueId() + " attribute value " + attValueData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR);
-		}
-	}
+    private void connectAttValueDataToAttData(Wrapper<TitanOperationStatus> errorWrapper, AttributeData attData, AttributeValueData attValueData) {
 
-	private void connectAttValueDataToAttData(Wrapper<TitanOperationStatus> errorWrapper, AttributeData attData, AttributeValueData attValueData) {
+        Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(attValueData, attData, GraphEdgeLabels.ATTRIBUTE_IMPL, null);
 
-		Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(attValueData, attData, GraphEdgeLabels.ATTRIBUTE_IMPL, null);
+        if (createRelResult.isRight()) {
+            TitanOperationStatus operationStatus = createRelResult.right().value();
+            BeEcompErrorManager.getInstance().logInternalFlowError("connectAttValueDataToAttData",
+                    "Failed to associate attribute value " + attValueData.getUniqueId() + " to attribute " + attData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR);
 
-		if (createRelResult.isRight()) {
-			TitanOperationStatus operationStatus = createRelResult.right().value();
-			BeEcompErrorManager.getInstance().logInternalFlowError("connectAttValueDataToAttData",
-					"Failed to associate attribute value " + attValueData.getUniqueId() + " to attribute " + attData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR);
+            errorWrapper.setInnerElement(operationStatus);
+        }
+    }
 
-			errorWrapper.setInnerElement(operationStatus);
-		}
-	}
+    private void createAttributeValueDataNode(ComponentInstanceProperty attributeInstanceProperty, Integer index, Wrapper<TitanOperationStatus> errorWrapper, ComponentInstanceData resourceInstanceData,
+            Wrapper<AttributeValueData> attValueDataWrapper) {
+        String valueUniqueUid = attributeInstanceProperty.getValueUniqueUid();
+        if (valueUniqueUid == null) {
 
-	private void createAttributeValueDataNode(ComponentInstanceProperty attributeInstanceProperty, Integer index, Wrapper<TitanOperationStatus> errorWrapper, ComponentInstanceData resourceInstanceData,
-			Wrapper<AttributeValueData> attValueDataWrapper) {
-		String valueUniqueUid = attributeInstanceProperty.getValueUniqueUid();
-		if (valueUniqueUid == null) {
+            String attValueDatauniqueId = UniqueIdBuilder.buildResourceInstanceAttributeValueUid(resourceInstanceData.getUniqueId(), index);
+            AttributeValueData attributeValueData = buildAttributeValueDataFromComponentInstanceAttribute(attributeInstanceProperty, attValueDatauniqueId);
 
-			String attValueDatauniqueId = UniqueIdBuilder.buildResourceInstanceAttributeValueUid(resourceInstanceData.getUniqueId(), index);
-			AttributeValueData attributeValueData = buildAttributeValueDataFromComponentInstanceAttribute(attributeInstanceProperty, attValueDatauniqueId);
+            log.debug("Before adding attribute value to graph {}", attributeValueData);
+            Either<AttributeValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(attributeValueData, AttributeValueData.class);
+            log.debug("After adding attribute value to graph {}", attributeValueData);
 
-			log.debug("Before adding attribute value to graph {}", attributeValueData);
-			Either<AttributeValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(attributeValueData, AttributeValueData.class);
-			log.debug("After adding attribute value to graph {}", attributeValueData);
+            if (createNodeResult.isRight()) {
+                TitanOperationStatus operationStatus = createNodeResult.right().value();
+                errorWrapper.setInnerElement(operationStatus);
+            } else {
+                attValueDataWrapper.setInnerElement(createNodeResult.left().value());
+            }
 
-			if (createNodeResult.isRight()) {
-				TitanOperationStatus operationStatus = createNodeResult.right().value();
-				errorWrapper.setInnerElement(operationStatus);
-			} else {
-				attValueDataWrapper.setInnerElement(createNodeResult.left().value());
-			}
+        } else {
+            BeEcompErrorManager.getInstance().logInternalFlowError("CreateAttributeValueDataNode", "attribute value already exists.", ErrorSeverity.ERROR);
+            errorWrapper.setInnerElement(TitanOperationStatus.ALREADY_EXIST);
+        }
+    }
 
-		} else {
-			BeEcompErrorManager.getInstance().logInternalFlowError("CreateAttributeValueDataNode", "attribute value already exists.", ErrorSeverity.ERROR);
-			errorWrapper.setInnerElement(TitanOperationStatus.ALREADY_EXIST);
-		}
-	}
+    private AttributeValueData buildAttributeValueDataFromComponentInstanceAttribute(ComponentInstanceProperty resourceInstanceAttribute, String uniqueId) {
+        AttributeValueData attributeValueData = new AttributeValueData();
+        attributeValueData.setUniqueId(uniqueId);
+        attributeValueData.setHidden(resourceInstanceAttribute.isHidden());
+        attributeValueData.setValue(resourceInstanceAttribute.getValue());
+        attributeValueData.setType(resourceInstanceAttribute.getType());
+        long currentTimeMillis = System.currentTimeMillis();
+        attributeValueData.setCreationTime(currentTimeMillis);
+        attributeValueData.setModificationTime(currentTimeMillis);
+        return attributeValueData;
+    }
 
-	private AttributeValueData buildAttributeValueDataFromComponentInstanceAttribute(ComponentInstanceProperty resourceInstanceAttribute, String uniqueId) {
-		AttributeValueData attributeValueData = new AttributeValueData();
-		attributeValueData.setUniqueId(uniqueId);
-		attributeValueData.setHidden(resourceInstanceAttribute.isHidden());
-		attributeValueData.setValue(resourceInstanceAttribute.getValue());
-		attributeValueData.setType(resourceInstanceAttribute.getType());
-		long currentTimeMillis = System.currentTimeMillis();
-		attributeValueData.setCreationTime(currentTimeMillis);
-		attributeValueData.setModificationTime(currentTimeMillis);
-		return attributeValueData;
-	}
+    private static final class UpdateDataContainer<SomeData, SomeValueData> {
+        final Wrapper<SomeValueData> valueDataWrapper;
+        final Wrapper<SomeData> dataWrapper;
+        final GraphEdgeLabels graphEdge;
+        final Supplier<Class<SomeData>> someDataClassGen;
+        final Supplier<Class<SomeValueData>> someValueDataClassGen;
+        final NodeTypeEnum nodeType;
+        final NodeTypeEnum nodeTypeValue;
 
-	private static final class UpdateDataContainer<SomeData, SomeValueData> {
-		final Wrapper<SomeValueData> valueDataWrapper;
-		final Wrapper<SomeData> dataWrapper;
-		final GraphEdgeLabels graphEdge;
-		final Supplier<Class<SomeData>> someDataClassGen;
-		final Supplier<Class<SomeValueData>> someValueDataClassGen;
-		final NodeTypeEnum nodeType;
-		final NodeTypeEnum nodeTypeValue;
+        private UpdateDataContainer(GraphEdgeLabels graphEdge, Supplier<Class<SomeData>> someDataClassGen, Supplier<Class<SomeValueData>> someValueDataClassGen, NodeTypeEnum nodeType, NodeTypeEnum nodeTypeValue) {
+            super();
+            this.valueDataWrapper = new Wrapper<>();
+            this.dataWrapper = new Wrapper<>();
+            this.graphEdge = graphEdge;
+            this.someDataClassGen = someDataClassGen;
+            this.someValueDataClassGen = someValueDataClassGen;
+            this.nodeType = nodeType;
+            this.nodeTypeValue = nodeTypeValue;
+        }
 
-		private UpdateDataContainer(GraphEdgeLabels graphEdge, Supplier<Class<SomeData>> someDataClassGen, Supplier<Class<SomeValueData>> someValueDataClassGen, NodeTypeEnum nodeType, NodeTypeEnum nodeTypeValue) {
-			super();
-			this.valueDataWrapper = new Wrapper<>();
-			this.dataWrapper = new Wrapper<>();
-			this.graphEdge = graphEdge;
-			this.someDataClassGen = someDataClassGen;
-			this.someValueDataClassGen = someValueDataClassGen;
-			this.nodeType = nodeType;
-			this.nodeTypeValue = nodeTypeValue;
-		}
+        public Wrapper<SomeValueData> getValueDataWrapper() {
+            return valueDataWrapper;
+        }
 
-		public Wrapper<SomeValueData> getValueDataWrapper() {
-			return valueDataWrapper;
-		}
+        public Wrapper<SomeData> getDataWrapper() {
+            return dataWrapper;
+        }
 
-		public Wrapper<SomeData> getDataWrapper() {
-			return dataWrapper;
-		}
+        public GraphEdgeLabels getGraphEdge() {
+            return graphEdge;
+        }
 
-		public GraphEdgeLabels getGraphEdge() {
-			return graphEdge;
-		}
+        public Supplier<Class<SomeData>> getSomeDataClassGen() {
+            return someDataClassGen;
+        }
 
-		public Supplier<Class<SomeData>> getSomeDataClassGen() {
-			return someDataClassGen;
-		}
+        public Supplier<Class<SomeValueData>> getSomeValueDataClassGen() {
+            return someValueDataClassGen;
+        }
 
-		public Supplier<Class<SomeValueData>> getSomeValueDataClassGen() {
-			return someValueDataClassGen;
-		}
+        public NodeTypeEnum getNodeType() {
+            return nodeType;
+        }
 
-		public NodeTypeEnum getNodeType() {
-			return nodeType;
-		}
+        public NodeTypeEnum getNodeTypeValue() {
+            return nodeTypeValue;
+        }
+    }
 
-		public NodeTypeEnum getNodeTypeValue() {
-			return nodeTypeValue;
-		}
-	}
+    /**
+     * update value of attribute on resource instance
+     *
+     * @param resourceInstanceAttribute
+     * @param resourceInstanceId
+     * @return
+     */
+    private Either<AttributeValueData, TitanOperationStatus> updateAttributeOfResourceInstance(ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId) {
 
-	/**
-	 * update value of attribute on resource instance
-	 * 
-	 * @param resourceInstanceAttribute
-	 * @param resourceInstanceId
-	 * @return
-	 */
-	private Either<AttributeValueData, TitanOperationStatus> updateAttributeOfResourceInstance(ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId) {
+        Either<AttributeValueData, TitanOperationStatus> result = null;
+        Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>();
+        UpdateDataContainer<AttributeData, AttributeValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.ATTRIBUTE_IMPL, (() -> AttributeData.class), (() -> AttributeValueData.class), NodeTypeEnum.Attribute,
+                NodeTypeEnum.AttributeValue);
+        preUpdateElementOfResourceInstanceValidations(updateDataContainer, resourceInstanceAttribute, resourceInstanceId, errorWrapper);
+        if (errorWrapper.isEmpty()) {
+            AttributeValueData attributeValueData = updateDataContainer.getValueDataWrapper().getInnerElement();
+            attributeValueData.setHidden(resourceInstanceAttribute.isHidden());
+            attributeValueData.setValue(resourceInstanceAttribute.getValue());
+            Either<AttributeValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(attributeValueData, AttributeValueData.class);
+            if (updateRes.isRight()) {
+                TitanOperationStatus status = updateRes.right().value();
+                errorWrapper.setInnerElement(status);
+            } else {
+                result = Either.left(updateRes.left().value());
+            }
+        }
+        if (!errorWrapper.isEmpty()) {
+            result = Either.right(errorWrapper.getInnerElement());
+        }
+        return result;
 
-		Either<AttributeValueData, TitanOperationStatus> result = null;
-		Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>();
-		UpdateDataContainer<AttributeData, AttributeValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.ATTRIBUTE_IMPL, (() -> AttributeData.class), (() -> AttributeValueData.class), NodeTypeEnum.Attribute,
-				NodeTypeEnum.AttributeValue);
-		preUpdateElementOfResourceInstanceValidations(updateDataContainer, resourceInstanceAttribute, resourceInstanceId, errorWrapper);
-		if (errorWrapper.isEmpty()) {
-			AttributeValueData attributeValueData = updateDataContainer.getValueDataWrapper().getInnerElement();
-			attributeValueData.setHidden(resourceInstanceAttribute.isHidden());
-			attributeValueData.setValue(resourceInstanceAttribute.getValue());
-			Either<AttributeValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(attributeValueData, AttributeValueData.class);
-			if (updateRes.isRight()) {
-				TitanOperationStatus status = updateRes.right().value();
-				errorWrapper.setInnerElement(status);
-			} else {
-				result = Either.left(updateRes.left().value());
-			}
-		}
-		if (!errorWrapper.isEmpty()) {
-			result = Either.right(errorWrapper.getInnerElement());
-		}
-		return result;
+    }
 
-	}
+    private Either<AttributeValueData, TitanOperationStatus> addAttributeToResourceInstance(ComponentInstanceProperty attributeInstanceProperty, String resourceInstanceId, Integer index) {
+        Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>();
+        Wrapper<ComponentInstanceData> compInsWrapper = new Wrapper<>();
+        Wrapper<AttributeData> attDataWrapper = new Wrapper<>();
+        Wrapper<AttributeValueData> attValueDataWrapper = new Wrapper<>();
 
-	private Either<AttributeValueData, TitanOperationStatus> addAttributeToResourceInstance(ComponentInstanceProperty attributeInstanceProperty, String resourceInstanceId, Integer index) {
-		Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>();
-		Wrapper<ComponentInstanceData> compInsWrapper = new Wrapper<>();
-		Wrapper<AttributeData> attDataWrapper = new Wrapper<>();
-		Wrapper<AttributeValueData> attValueDataWrapper = new Wrapper<>();
+        // Verify RI Exist
+        validateRIExist(resourceInstanceId, compInsWrapper, errorWrapper);
 
-		// Verify RI Exist
-		validateRIExist(resourceInstanceId, compInsWrapper, errorWrapper);
+        if (errorWrapper.isEmpty()) {
+            // Verify Attribute Exist
+            validateElementExistInGraph(attributeInstanceProperty.getUniqueId(), NodeTypeEnum.Attribute, () -> AttributeData.class, attDataWrapper, errorWrapper);
+        }
+        if (errorWrapper.isEmpty()) {
+            // Create AttributeValueData that is connected to RI
+            createAttributeValueDataNode(attributeInstanceProperty, index, errorWrapper, compInsWrapper.getInnerElement(), attValueDataWrapper);
+        }
+        if (errorWrapper.isEmpty()) {
+            // Connect AttributeValueData (Att on RI) to AttData (Att on
+            // Resource)
+            connectAttValueDataToAttData(errorWrapper, attDataWrapper.getInnerElement(), attValueDataWrapper.getInnerElement());
+        }
+        if (errorWrapper.isEmpty()) {
+            // Connect AttributeValueData to RI
+            connectAttValueDataToComponentInstanceData(errorWrapper, compInsWrapper.getInnerElement(), attValueDataWrapper.getInnerElement());
+        }
 
-		if (errorWrapper.isEmpty()) {
-			// Verify Attribute Exist
-			validateElementExistInGraph(attributeInstanceProperty.getUniqueId(), NodeTypeEnum.Attribute, () -> AttributeData.class, attDataWrapper, errorWrapper);
-		}
-		if (errorWrapper.isEmpty()) {
-			// Create AttributeValueData that is connected to RI
-			createAttributeValueDataNode(attributeInstanceProperty, index, errorWrapper, compInsWrapper.getInnerElement(), attValueDataWrapper);
-		}
-		if (errorWrapper.isEmpty()) {
-			// Connect AttributeValueData (Att on RI) to AttData (Att on
-			// Resource)
-			connectAttValueDataToAttData(errorWrapper, attDataWrapper.getInnerElement(), attValueDataWrapper.getInnerElement());
-		}
-		if (errorWrapper.isEmpty()) {
-			// Connect AttributeValueData to RI
-			connectAttValueDataToComponentInstanceData(errorWrapper, compInsWrapper.getInnerElement(), attValueDataWrapper.getInnerElement());
-		}
+        if (errorWrapper.isEmpty()) {
+            return Either.left(attValueDataWrapper.getInnerElement());
+        } else {
+            return Either.right(errorWrapper.getInnerElement());
+        }
 
-		if (errorWrapper.isEmpty()) {
-			return Either.left(attValueDataWrapper.getInnerElement());
-		} else {
-			return Either.right(errorWrapper.getInnerElement());
-		}
+    }
 
-	}
+    private <SomeData extends GraphNode, SomeValueData extends GraphNode> void preUpdateElementOfResourceInstanceValidations(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
+            String resourceInstanceId, Wrapper<TitanOperationStatus> errorWrapper) {
 
-	private <SomeData extends GraphNode, SomeValueData extends GraphNode> void preUpdateElementOfResourceInstanceValidations(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
-			String resourceInstanceId, Wrapper<TitanOperationStatus> errorWrapper) {
+        if (errorWrapper.isEmpty()) {
+            // Verify VFC instance Exist
+            validateRIExist(resourceInstanceId, errorWrapper);
+        }
 
-		if (errorWrapper.isEmpty()) {
-			// Verify VFC instance Exist
-			validateRIExist(resourceInstanceId, errorWrapper);
-		}
+        if (errorWrapper.isEmpty()) {
+            // Example: Verify Property connected to VFC exist
+            validateElementConnectedToComponentExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
+        }
 
-		if (errorWrapper.isEmpty()) {
-			// Example: Verify Property connected to VFC exist
-			validateElementConnectedToComponentExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
-		}
+        if (errorWrapper.isEmpty()) {
+            // Example: Verify PropertyValue connected to VFC Instance exist
+            validateElementConnectedToComponentInstanceExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
+        }
 
-		if (errorWrapper.isEmpty()) {
-			// Example: Verify PropertyValue connected to VFC Instance exist
-			validateElementConnectedToComponentInstanceExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
-		}
+        if (errorWrapper.isEmpty()) {
+            // Example: Verify PropertyValue connected Property
+            validateElementConnectedToInstance(updateDataContainer, resourceInstanceProerty, errorWrapper);
+        }
+    }
 
-		if (errorWrapper.isEmpty()) {
-			// Example: Verify PropertyValue connected Property
-			validateElementConnectedToInstance(updateDataContainer, resourceInstanceProerty, errorWrapper);
-		}
-	}
+    private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToInstance(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
+            Wrapper<TitanOperationStatus> errorWrapper) {
+        Either<ImmutablePair<SomeData, GraphEdge>, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), resourceInstanceProerty.getValueUniqueUid(),
+                updateDataContainer.getGraphEdge(), updateDataContainer.getNodeType(), updateDataContainer.getSomeDataClassGen().get());
 
-	private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToInstance(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
-			Wrapper<TitanOperationStatus> errorWrapper) {
-		Either<ImmutablePair<SomeData, GraphEdge>, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), resourceInstanceProerty.getValueUniqueUid(),
-				updateDataContainer.getGraphEdge(), updateDataContainer.getNodeType(), updateDataContainer.getSomeDataClassGen().get());
+        if (child.isRight()) {
+            TitanOperationStatus status = child.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            errorWrapper.setInnerElement(status);
 
-		if (child.isRight()) {
-			TitanOperationStatus status = child.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			errorWrapper.setInnerElement(status);
+        } else {
+            updateDataContainer.getDataWrapper().setInnerElement(child.left().value().left);
+        }
+    }
 
-		} else {
-			updateDataContainer.getDataWrapper().setInnerElement(child.left().value().left);
-		}
-	}
+    private <SomeValueData extends GraphNode, SomeData extends GraphNode> void validateElementConnectedToComponentInstanceExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer,
+            IComponentInstanceConnectedElement resourceInstanceProerty, Wrapper<TitanOperationStatus> errorWrapper) {
+        String valueUniqueUid = resourceInstanceProerty.getValueUniqueUid();
+        if (valueUniqueUid == null) {
+            errorWrapper.setInnerElement(TitanOperationStatus.INVALID_ID);
+        } else {
+            Either<SomeValueData, TitanOperationStatus> findPropertyValueRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), valueUniqueUid, updateDataContainer.getSomeValueDataClassGen().get());
+            if (findPropertyValueRes.isRight()) {
+                TitanOperationStatus status = findPropertyValueRes.right().value();
+                if (status == TitanOperationStatus.NOT_FOUND) {
+                    status = TitanOperationStatus.INVALID_ID;
+                }
+                errorWrapper.setInnerElement(status);
+            } else {
+                updateDataContainer.getValueDataWrapper().setInnerElement(findPropertyValueRes.left().value());
+            }
+        }
+    }
 
-	private <SomeValueData extends GraphNode, SomeData extends GraphNode> void validateElementConnectedToComponentInstanceExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer,
-			IComponentInstanceConnectedElement resourceInstanceProerty, Wrapper<TitanOperationStatus> errorWrapper) {
-		String valueUniqueUid = resourceInstanceProerty.getValueUniqueUid();
-		if (valueUniqueUid == null) {
-			errorWrapper.setInnerElement(TitanOperationStatus.INVALID_ID);
-		} else {
-			Either<SomeValueData, TitanOperationStatus> findPropertyValueRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), valueUniqueUid, updateDataContainer.getSomeValueDataClassGen().get());
-			if (findPropertyValueRes.isRight()) {
-				TitanOperationStatus status = findPropertyValueRes.right().value();
-				if (status == TitanOperationStatus.NOT_FOUND) {
-					status = TitanOperationStatus.INVALID_ID;
-				}
-				errorWrapper.setInnerElement(status);
-			} else {
-				updateDataContainer.getValueDataWrapper().setInnerElement(findPropertyValueRes.left().value());
-			}
-		}
-	}
+    private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToComponentExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer,
+            IComponentInstanceConnectedElement resourceInstanceElementConnected, Wrapper<TitanOperationStatus> errorWrapper) {
+        String uniqueId = resourceInstanceElementConnected.getUniqueId();
+        Either<SomeData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeType()), uniqueId, updateDataContainer.getSomeDataClassGen().get());
 
-	private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToComponentExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer,
-			IComponentInstanceConnectedElement resourceInstanceElementConnected, Wrapper<TitanOperationStatus> errorWrapper) {
-		String uniqueId = resourceInstanceElementConnected.getUniqueId();
-		Either<SomeData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeType()), uniqueId, updateDataContainer.getSomeDataClassGen().get());
-
-		if (findPropertyDefRes.isRight()) {
-			TitanOperationStatus status = findPropertyDefRes.right().value();
-			errorWrapper.setInnerElement(status);
-		}
-	}
+        if (findPropertyDefRes.isRight()) {
+            TitanOperationStatus status = findPropertyDefRes.right().value();
+            errorWrapper.setInnerElement(status);
+        }
+    }
 
-	private void validateRIExist(String resourceInstanceId, Wrapper<TitanOperationStatus> errorWrapper) {
-		validateRIExist(resourceInstanceId, null, errorWrapper);
-	}
+    private void validateRIExist(String resourceInstanceId, Wrapper<TitanOperationStatus> errorWrapper) {
+        validateRIExist(resourceInstanceId, null, errorWrapper);
+    }
 
-	private void validateRIExist(String resourceInstanceId, Wrapper<ComponentInstanceData> compInsDataWrapper, Wrapper<TitanOperationStatus> errorWrapper) {
-		validateElementExistInGraph(resourceInstanceId, NodeTypeEnum.ResourceInstance, () -> ComponentInstanceData.class, compInsDataWrapper, errorWrapper);
-	}
+    private void validateRIExist(String resourceInstanceId, Wrapper<ComponentInstanceData> compInsDataWrapper, Wrapper<TitanOperationStatus> errorWrapper) {
+        validateElementExistInGraph(resourceInstanceId, NodeTypeEnum.ResourceInstance, () -> ComponentInstanceData.class, compInsDataWrapper, errorWrapper);
+    }
 
-	public <ElementData extends GraphNode> void validateElementExistInGraph(String elementUniqueId, NodeTypeEnum elementNodeType, Supplier<Class<ElementData>> elementClassGen, Wrapper<ElementData> elementDataWrapper,
-			Wrapper<TitanOperationStatus> errorWrapper) {
-		Either<ElementData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(elementNodeType), elementUniqueId, elementClassGen.get());
-		if (findResInstanceRes.isRight()) {
-			TitanOperationStatus status = findResInstanceRes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			errorWrapper.setInnerElement(status);
-		} else {
-			if (elementDataWrapper != null) {
-				elementDataWrapper.setInnerElement(findResInstanceRes.left().value());
-			}
-		}
-	}
+    public <ElementData extends GraphNode> void validateElementExistInGraph(String elementUniqueId, NodeTypeEnum elementNodeType, Supplier<Class<ElementData>> elementClassGen, Wrapper<ElementData> elementDataWrapper,
+            Wrapper<TitanOperationStatus> errorWrapper) {
+        Either<ElementData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(elementNodeType), elementUniqueId, elementClassGen.get());
+        if (findResInstanceRes.isRight()) {
+            TitanOperationStatus status = findResInstanceRes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            errorWrapper.setInnerElement(status);
+        } else {
+            if (elementDataWrapper != null) {
+                elementDataWrapper.setInnerElement(findResInstanceRes.left().value());
+            }
+        }
+    }
 
-	/**
-	 * add property to resource instance
-	 * 
-	 * @param resourceInstanceId
-	 * @param index
-	 * @return
-	 */
-	private Either<InputValueData, TitanOperationStatus> addInputToResourceInstance(ComponentInstanceInput resourceInstanceInput, String resourceInstanceId, Integer index) {
+    /**
+     * add property to resource instance
+     *
+     * @param resourceInstanceId
+     * @param index
+     * @return
+     */
+    private Either<InputValueData, TitanOperationStatus> addInputToResourceInstance(ComponentInstanceInput resourceInstanceInput, String resourceInstanceId, Integer index) {
 
-		Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
+        Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
 
-		if (findResInstanceRes.isRight()) {
-			TitanOperationStatus status = findResInstanceRes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			return Either.right(status);
-		}
+        if (findResInstanceRes.isRight()) {
+            TitanOperationStatus status = findResInstanceRes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            return Either.right(status);
+        }
 
-		String propertyId = resourceInstanceInput.getUniqueId();
-		Either<InputsData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), propertyId, InputsData.class);
+        String propertyId = resourceInstanceInput.getUniqueId();
+        Either<InputsData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), propertyId, InputsData.class);
 
-		if (findPropertyDefRes.isRight()) {
-			TitanOperationStatus status = findPropertyDefRes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			return Either.right(status);
-		}
+        if (findPropertyDefRes.isRight()) {
+            TitanOperationStatus status = findPropertyDefRes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            return Either.right(status);
+        }
 
-		String valueUniqueUid = resourceInstanceInput.getValueUniqueUid();
-		if (valueUniqueUid == null) {
+        String valueUniqueUid = resourceInstanceInput.getValueUniqueUid();
+        if (valueUniqueUid == null) {
 
-			InputsData propertyData = findPropertyDefRes.left().value();
+            InputsData propertyData = findPropertyDefRes.left().value();
 
-			ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value();
+            ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value();
 
-			ImmutablePair<TitanOperationStatus, String> isInputValueExists = inputOperation.findInputValue(resourceInstanceId, propertyId);
-			if (isInputValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) {
-				log.debug("The property {} already added to the resource instance {}", propertyId, resourceInstanceId);
-				resourceInstanceInput.setValueUniqueUid(isInputValueExists.getRight());
-				/*
-				 * Either<InputValueData, TitanOperationStatus> updatePropertyOfResourceInstance = updatePropertyOfResourceInstance(resourceInstanceInput, resourceInstanceId); if (updatePropertyOfResourceInstance.isRight()) {
-				 * BeEcompErrorManager.getInstance().logInternalFlowError( "UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR);
-				 * return Either.right(updatePropertyOfResourceInstance.right().value() ); } return Either.left(updatePropertyOfResourceInstance.left().value());
-				 */
-			}
+            ImmutablePair<TitanOperationStatus, String> isInputValueExists = inputOperation.findInputValue(resourceInstanceId, propertyId);
+            if (isInputValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) {
+                log.debug("The property {} already added to the resource instance {}", propertyId, resourceInstanceId);
+                resourceInstanceInput.setValueUniqueUid(isInputValueExists.getRight());
+            }
 
-			if (isInputValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) {
-				log.debug("After finding input value of {} on componenet instance {}", propertyId, resourceInstanceId);
-				return Either.right(isInputValueExists.getLeft());
-			}
+            if (isInputValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) {
+                log.debug("After finding input value of {} on componenet instance {}", propertyId, resourceInstanceId);
+                return Either.right(isInputValueExists.getLeft());
+            }
 
-			String innerType = null;
+            String innerType = null;
 
-			PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
-			String propertyType = propDataDef.getType();
-			String value = resourceInstanceInput.getValue();
-			ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
+            PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
+            String propertyType = propDataDef.getType();
+            String value = resourceInstanceInput.getValue();
+            ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
 
-			if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
-				SchemaDefinition def = propDataDef.getSchema();
-				if (def == null) {
-					log.debug("Schema doesn't exists for property of type {}", type);
-					return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-				}
-				PropertyDataDefinition propDef = def.getProperty();
-				if (propDef == null) {
-					log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
-					return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-				}
-				innerType = propDef.getType();
-			}
+            if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
+                SchemaDefinition def = propDataDef.getSchema();
+                if (def == null) {
+                    log.debug("Schema doesn't exists for property of type {}", type);
+                    return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+                }
+                PropertyDataDefinition propDef = def.getProperty();
+                if (propDef == null) {
+                    log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
+                    return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+                }
+                innerType = propDef.getType();
+            }
 
-			log.debug("Before validateAndUpdatePropertyValue");
-			Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
-			if (allDataTypes.isRight()) {
-				TitanOperationStatus status = allDataTypes.right().value();
-				BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR);
-				return Either.right(status);
-			}
+            log.debug("Before validateAndUpdatePropertyValue");
+            Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
+            if (allDataTypes.isRight()) {
+                TitanOperationStatus status = allDataTypes.right().value();
+                BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR);
+                return Either.right(status);
+            }
 
-			String uniqueId = UniqueIdBuilder.buildResourceInstanceInputValueUid(resourceInstanceData.getUniqueId(), index);
-			InputValueData propertyValueData = new InputValueData();
-			propertyValueData.setUniqueId(uniqueId);
-			propertyValueData.setValue(value);
+            String uniqueId = UniqueIdBuilder.buildResourceInstanceInputValueUid(resourceInstanceData.getUniqueId(), index);
+            InputValueData propertyValueData = new InputValueData();
+            propertyValueData.setUniqueId(uniqueId);
+            propertyValueData.setValue(value);
 
-			log.debug("Before validateAndUpdateRules");
-			ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceInput.getRules(), innerType, allDataTypes.left().value(), true);
-			log.debug("After validateAndUpdateRules. pair = {} ", pair);
-			if (pair.getRight() != null && pair.getRight() == false) {
-				BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceInput.getName(), propertyType);
-				return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-			}
-			// propertyOperation.addRulesToNewPropertyValue(propertyValueData,
-			// resourceInstanceInput, resourceInstanceId);
+            log.debug("Before validateAndUpdateRules");
+            ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceInput.getRules(), innerType, allDataTypes.left().value(), true);
+            log.debug("After validateAndUpdateRules. pair = {} ", pair);
+            if (pair.getRight() != null && !pair.getRight()) {
+                BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceInput.getName(), propertyType);
+                return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+            }
+            log.debug("Before adding property value to graph {}", propertyValueData);
+            Either<InputValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyValueData, InputValueData.class);
+            log.debug("After adding property value to graph {}", propertyValueData);
 
-			log.debug("Before adding property value to graph {}", propertyValueData);
-			Either<InputValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyValueData, InputValueData.class);
-			log.debug("After adding property value to graph {}", propertyValueData);
+            if (createNodeResult.isRight()) {
+                TitanOperationStatus operationStatus = createNodeResult.right().value();
+                return Either.right(operationStatus);
+            }
 
-			if (createNodeResult.isRight()) {
-				TitanOperationStatus operationStatus = createNodeResult.right().value();
-				return Either.right(operationStatus);
-			}
+            Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(propertyValueData, propertyData, GraphEdgeLabels.INPUT_IMPL, null);
 
-			Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(propertyValueData, propertyData, GraphEdgeLabels.INPUT_IMPL, null);
+            if (createRelResult.isRight()) {
+                TitanOperationStatus operationStatus = createRelResult.right().value();
+                log.error("Failed to associate property value {} to property {} in graph. status is {}", uniqueId, propertyId, operationStatus);
+                return Either.right(operationStatus);
+            }
 
-			if (createRelResult.isRight()) {
-				TitanOperationStatus operationStatus = createRelResult.right().value();
-				log.error("Failed to associate property value {} to property {} in graph. status is {}", uniqueId, propertyId, operationStatus);
-				return Either.right(operationStatus);
-			}
+            Map<String, Object> properties1 = new HashMap<>();
 
-			Map<String, Object> properties1 = new HashMap<String, Object>();
+            properties1.put(GraphEdgePropertiesDictionary.NAME.getProperty(), resourceInstanceData.getComponentInstDataDefinition().getName());
+            properties1.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), resourceInstanceData.getComponentInstDataDefinition().getUniqueId());
 
-			properties1.put(GraphEdgePropertiesDictionary.NAME.getProperty(), resourceInstanceData.getComponentInstDataDefinition().getName());
-			properties1.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), resourceInstanceData.getComponentInstDataDefinition().getUniqueId());
+            createRelResult = titanGenericDao.createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.INPUT_VALUE, properties1);
 
-			createRelResult = titanGenericDao.createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.INPUT_VALUE, properties1);
+            if (createRelResult.isRight()) {
+                TitanOperationStatus operationStatus = createNodeResult.right().value();
+                log.error("Failed to associate resource instance {} property value {} in graph. status is {}", resourceInstanceId, uniqueId, operationStatus);
+                return Either.right(operationStatus);
 
-			if (createRelResult.isRight()) {
-				TitanOperationStatus operationStatus = createNodeResult.right().value();
-				log.error("Failed to associate resource instance {} property value {} in graph. status is {}", resourceInstanceId, uniqueId, operationStatus);
-				return Either.right(operationStatus);
+            }
 
-			}
+            return Either.left(createNodeResult.left().value());
+        } else {
+            log.error("property value already exists.");
+            return Either.right(TitanOperationStatus.ALREADY_EXIST);
+        }
 
-			return Either.left(createNodeResult.left().value());
-		} else {
-			log.error("property value already exists.");
-			return Either.right(TitanOperationStatus.ALREADY_EXIST);
-		}
+    }
 
-	}
+    @Override
+    public Either<ComponentInstanceProperty, StorageOperationStatus> addAttributeValueToResourceInstance(ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId, Integer index, boolean inTransaction) {
+        Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
 
-	@Override
-	public Either<ComponentInstanceProperty, StorageOperationStatus> addAttributeValueToResourceInstance(ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId, Integer index, boolean inTransaction) {
-		Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
+        try {
 
-		try {
+            Either<AttributeValueData, TitanOperationStatus> eitherStatus = this.addAttributeToResourceInstance(resourceInstanceAttribute, resourceInstanceId, index);
 
-			Either<AttributeValueData, TitanOperationStatus> eitherStatus = this.addAttributeToResourceInstance(resourceInstanceAttribute, resourceInstanceId, index);
+            if (eitherStatus.isRight()) {
+                log.error("Failed to add attribute value {} to resource instance {} in Graph. status is {}", resourceInstanceAttribute, resourceInstanceId, eitherStatus.right().value().name());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
+                return result;
+            } else {
+                AttributeValueData attributeValueData = eitherStatus.left().value();
 
-			if (eitherStatus.isRight()) {
-				log.error("Failed to add attribute value {} to resource instance {} in Graph. status is {}", resourceInstanceAttribute, resourceInstanceId, eitherStatus.right().value().name());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
-				return result;
-			} else {
-				AttributeValueData attributeValueData = eitherStatus.left().value();
+                ComponentInstanceProperty attributeValueResult = buildResourceInstanceAttribute(attributeValueData, resourceInstanceAttribute);
+                log.debug("The returned ResourceInstanceAttribute is {}", attributeValueResult);
 
-				ComponentInstanceProperty attributeValueResult = buildResourceInstanceAttribute(attributeValueData, resourceInstanceAttribute);
-				log.debug("The returned ResourceInstanceAttribute is {}", attributeValueResult);
+                result = Either.left(attributeValueResult);
+                return result;
+            }
+        }
 
-				result = Either.left(attributeValueResult);
-				return result;
-			}
-		}
+        finally {
+            handleTransactionCommitRollback(inTransaction, result);
+        }
+    }
 
-		finally {
-			handleTransactionCommitRollback(inTransaction, result);
-		}
-	}
+    private ComponentInstanceProperty buildResourceInstanceAttribute(AttributeValueData attributeValueData, ComponentInstanceProperty resourceInstanceAttribute) {
+        Boolean hidden = attributeValueData.isHidden();
+        String uid = attributeValueData.getUniqueId();
+        return new ComponentInstanceProperty(hidden, resourceInstanceAttribute, uid);
+    }
 
-	private ComponentInstanceProperty buildResourceInstanceAttribute(AttributeValueData attributeValueData, ComponentInstanceProperty resourceInstanceAttribute) {
-		Boolean hidden = attributeValueData.isHidden();
-		String uid = attributeValueData.getUniqueId();
-		return new ComponentInstanceProperty(hidden, resourceInstanceAttribute, uid);
-	}
+    @Override
+    public Either<ComponentInstanceProperty, StorageOperationStatus> updateAttributeValueInResourceInstance(ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId, boolean inTransaction) {
 
-	@Override
-	public Either<ComponentInstanceProperty, StorageOperationStatus> updateAttributeValueInResourceInstance(ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId, boolean inTransaction) {
+        Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
 
-		Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
+        try {
+            Either<AttributeValueData, TitanOperationStatus> eitherAttributeValue = updateAttributeOfResourceInstance(resourceInstanceAttribute, resourceInstanceId);
 
-		try {
-			Either<AttributeValueData, TitanOperationStatus> eitherAttributeValue = updateAttributeOfResourceInstance(resourceInstanceAttribute, resourceInstanceId);
+            if (eitherAttributeValue.isRight()) {
+                log.error("Failed to add attribute value {} to resource instance {} in Graph. status is {}", resourceInstanceAttribute, resourceInstanceId, eitherAttributeValue.right().value().name());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherAttributeValue.right().value()));
+                return result;
+            } else {
+                AttributeValueData attributeValueData = eitherAttributeValue.left().value();
 
-			if (eitherAttributeValue.isRight()) {
-				log.error("Failed to add attribute value {} to resource instance {} in Graph. status is {}", resourceInstanceAttribute, resourceInstanceId, eitherAttributeValue.right().value().name());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherAttributeValue.right().value()));
-				return result;
-			} else {
-				AttributeValueData attributeValueData = eitherAttributeValue.left().value();
+                ComponentInstanceProperty attributeValueResult = buildResourceInstanceAttribute(attributeValueData, resourceInstanceAttribute);
+                log.debug("The returned ResourceInstanceAttribute is {}", attributeValueResult);
 
-				ComponentInstanceProperty attributeValueResult = buildResourceInstanceAttribute(attributeValueData, resourceInstanceAttribute);
-				log.debug("The returned ResourceInstanceAttribute is {}", attributeValueResult);
+                result = Either.left(attributeValueResult);
+                return result;
+            }
+        }
 
-				result = Either.left(attributeValueResult);
-				return result;
-			}
-		}
+        finally {
+            handleTransactionCommitRollback(inTransaction, result);
+        }
 
-		finally {
-			handleTransactionCommitRollback(inTransaction, result);
-		}
+    }
 
-	}
+    @Override
+    public Either<ComponentInstanceInput, StorageOperationStatus> addInputValueToResourceInstance(ComponentInstanceInput resourceInstanceInput, String resourceInstanceId, Integer index, boolean inTransaction) {
 
-	@Override
-	public Either<ComponentInstanceInput, StorageOperationStatus> addInputValueToResourceInstance(ComponentInstanceInput resourceInstanceInput, String resourceInstanceId, Integer index, boolean inTransaction) {
+        /// #RULES SUPPORT
+        /// Ignore rules received from client till support
+        resourceInstanceInput.setRules(null);
+        ///
+        ///
 
-		/// #RULES SUPPORT
-		/// Ignore rules received from client till support
-		resourceInstanceInput.setRules(null);
-		///
-		///
+        Either<ComponentInstanceInput, StorageOperationStatus> result = null;
 
-		Either<ComponentInstanceInput, StorageOperationStatus> result = null;
+        try {
 
-		try {
+            Either<InputValueData, TitanOperationStatus> eitherStatus = addInputToResourceInstance(resourceInstanceInput, resourceInstanceId, index);
 
-			Either<InputValueData, TitanOperationStatus> eitherStatus = addInputToResourceInstance(resourceInstanceInput, resourceInstanceId, index);
+            if (eitherStatus.isRight()) {
+                log.error("Failed to add input value {} to resource instance {} in Graph. status is {}", resourceInstanceInput, resourceInstanceId, eitherStatus.right().value().name());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
+                return result;
+            } else {
+                InputValueData propertyValueData = eitherStatus.left().value();
 
-			if (eitherStatus.isRight()) {
-				log.error("Failed to add input value {} to resource instance {} in Graph. status is {}", resourceInstanceInput, resourceInstanceId, eitherStatus.right().value().name());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
-				return result;
-			} else {
-				InputValueData propertyValueData = eitherStatus.left().value();
+                ComponentInstanceInput propertyValueResult = inputOperation.buildResourceInstanceInput(propertyValueData, resourceInstanceInput);
+                log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult);
 
-				ComponentInstanceInput propertyValueResult = inputOperation.buildResourceInstanceInput(propertyValueData, resourceInstanceInput);
-				log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult);
+                Either<String, TitanOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(resourceInstanceInput.getPath(), resourceInstanceInput.getUniqueId(), resourceInstanceInput.getDefaultValue());
+                if (findDefaultValue.isRight()) {
+                    result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value()));
+                    return result;
+                }
+                String defaultValue = findDefaultValue.left().value();
+                propertyValueResult.setDefaultValue(defaultValue);
+                log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue);
 
-				Either<String, TitanOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(resourceInstanceInput.getPath(), resourceInstanceInput.getUniqueId(), resourceInstanceInput.getDefaultValue());
-				if (findDefaultValue.isRight()) {
-					result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value()));
-					return result;
-				}
-				String defaultValue = findDefaultValue.left().value();
-				propertyValueResult.setDefaultValue(defaultValue);
-				log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue);
+                result = Either.left(propertyValueResult);
+                return result;
+            }
+        }
 
-				result = Either.left(propertyValueResult);
-				return result;
-			}
-		}
+        finally {
+            if (!inTransaction) {
+                if (result == null || result.isRight()) {
+                    log.error("Going to execute rollback on graph.");
+                    titanGenericDao.rollback();
+                } else {
+                    log.debug("Going to execute commit on graph.");
+                    titanGenericDao.commit();
+                }
+            }
+        }
 
-		finally {
-			if (false == inTransaction) {
-				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
-					titanGenericDao.rollback();
-				} else {
-					log.debug("Going to execute commit on graph.");
-					titanGenericDao.commit();
-				}
-			}
-		}
+    }
 
-	}
+    @Override
+    public Either<ComponentInstanceInput, StorageOperationStatus> updateInputValueInResourceInstance(ComponentInstanceInput input, String resourceInstanceId, boolean b) {
+        return null;
+    }
 
-	@Override
-	public Either<ComponentInstanceInput, StorageOperationStatus> updateInputValueInResourceInstance(ComponentInstanceInput input, String resourceInstanceId, boolean b) {
-		return null;
-	}
+    @Override
+    public StorageOperationStatus updateCustomizationUUID(String componentInstanceId) {
+        Either<TitanVertex, TitanOperationStatus> vertexByProperty = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), componentInstanceId);
+        if (vertexByProperty.isRight()) {
+            log.debug("Failed to fetch component instance by id {} error {}", componentInstanceId, vertexByProperty.right().value());
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(vertexByProperty.right().value());
+        }
+        UUID uuid = UUID.randomUUID();
+        TitanVertex ciVertex = vertexByProperty.left().value();
+        ciVertex.property(GraphPropertiesDictionary.CUSTOMIZATION_UUID.getProperty(), uuid.toString());
 
-	@Override
-	public StorageOperationStatus updateCustomizationUUID(String componentInstanceId) {
-		Either<TitanVertex, TitanOperationStatus> vertexByProperty = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), componentInstanceId);
-		if (vertexByProperty.isRight()) {
-			log.debug("Failed to fetch component instance by id {} error {}", componentInstanceId, vertexByProperty.right().value());
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(vertexByProperty.right().value());
-		}
-		UUID uuid = UUID.randomUUID();
-		TitanVertex ciVertex = vertexByProperty.left().value();
-		ciVertex.property(GraphPropertiesDictionary.CUSTOMIZATION_UUID.getProperty(), uuid.toString());
+        return StorageOperationStatus.OK;
+    }
 
-		return StorageOperationStatus.OK;
-	}
+    @Override
+    public Either<ComponentInstanceData, StorageOperationStatus> updateComponentInstanceModificationTimeAndCustomizationUuidOnGraph(ComponentInstance componentInstance, NodeTypeEnum componentInstanceType, Long modificationTime, boolean inTransaction) {
 
-	@Override
-	public Either<ComponentInstanceData, StorageOperationStatus> updateComponentInstanceModificationTimeAndCustomizationUuidOnGraph(ComponentInstance componentInstance, NodeTypeEnum componentInstanceType, Long modificationTime, boolean inTransaction) {
-		
-		log.debug("Going to update modification time of component instance {}. ", componentInstance.getName());
-		Either<ComponentInstanceData, StorageOperationStatus> result = null;
-		try{
-			ComponentInstanceData componentData = new ComponentInstanceData(componentInstance, componentInstance.getGroupInstances().size());
-			componentData.getComponentInstDataDefinition().setModificationTime(modificationTime);
-			componentData.getComponentInstDataDefinition().setCustomizationUUID(UUID.randomUUID().toString());
-			Either<ComponentInstanceData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(componentData, ComponentInstanceData.class);
-			if (updateNode.isRight()) {
-				log.error("Failed to update resource {}. status is {}", componentInstance.getUniqueId(), updateNode.right().value());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value()));
-			}else{
-				result = Either.left(updateNode.left().value());
-			}
-		}catch(Exception e){
-			log.error("Exception occured during  update modification date of compomemt instance{}. The message is {}. ", componentInstance.getName(), e.getMessage(), e);
-			result = Either.right(StorageOperationStatus.GENERAL_ERROR);
-		}finally {
-			if(!inTransaction){
-				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
-					titanGenericDao.rollback();
-				} else {
-					log.debug("Going to execute commit on graph.");
-					titanGenericDao.commit();
-				}
-			}
-		}
-		return result;
-	}
+        log.debug("Going to update modification time of component instance {}. ", componentInstance.getName());
+        Either<ComponentInstanceData, StorageOperationStatus> result = null;
+        try{
+            ComponentInstanceData componentData = new ComponentInstanceData(componentInstance, componentInstance.getGroupInstances().size());
+            componentData.getComponentInstDataDefinition().setModificationTime(modificationTime);
+            componentData.getComponentInstDataDefinition().setCustomizationUUID(UUID.randomUUID().toString());
+            Either<ComponentInstanceData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(componentData, ComponentInstanceData.class);
+            if (updateNode.isRight()) {
+                log.error("Failed to update resource {}. status is {}", componentInstance.getUniqueId(), updateNode.right().value());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value()));
+            }else{
+                result = Either.left(updateNode.left().value());
+            }
+        }catch(Exception e){
+            log.error("Exception occured during  update modification date of compomemt instance{}. The message is {}. ", componentInstance.getName(), e.getMessage(), e);
+            result = Either.right(StorageOperationStatus.GENERAL_ERROR);
+        }finally {
+            if(!inTransaction){
+                if (result == null || result.isRight()) {
+                    log.error("Going to execute rollback on graph.");
+                    titanGenericDao.rollback();
+                } else {
+                    log.debug("Going to execute commit on graph.");
+                    titanGenericDao.commit();
+                }
+            }
+        }
+        return result;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.java
index 198ad99..c173b59 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.java
@@ -20,9 +20,7 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.Collections;
-import java.util.List;
-
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
@@ -30,134 +28,134 @@
 import org.openecomp.sdc.be.model.operations.api.IConsumerOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.resources.data.ConsumerData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
 
-import fj.data.Either;
+import java.util.Collections;
+import java.util.List;
 
 @Component("consumer-operation")
 public class ConsumerOperation implements IConsumerOperation {
 
-	private TitanGenericDao titanGenericDao;
+    private TitanGenericDao titanGenericDao;
 
-	private static Logger log = LoggerFactory.getLogger(ConsumerOperation.class.getName());
+    private static final Logger log = Logger.getLogger(ConsumerOperation.class.getName());
 
-	public ConsumerOperation(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao) {
-		this.titanGenericDao = titanGenericDao;
-	}
+    public ConsumerOperation(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao) {
+        this.titanGenericDao = titanGenericDao;
+    }
 
-	@Override
-	public Either<ConsumerData, StorageOperationStatus> getCredentials(String consumerName) {
-		Either<ConsumerData, StorageOperationStatus> result = null;
-		log.debug("retriving Credentials for: {}", consumerName);
-		Either<ConsumerData, TitanOperationStatus> getNode = titanGenericDao.getNode(GraphPropertiesDictionary.CONSUMER_NAME.getProperty(), consumerName, ConsumerData.class);
-		if (getNode.isRight()) {
-			TitanOperationStatus status = getNode.right().value();
-			log.error("Error returned after get Consumer Data node {}. status returned is {}", consumerName, status);
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			return result;
-		}
-		ConsumerData consumerData = getNode.left().value();
-		return Either.left(consumerData);
-	}
+    @Override
+    public Either<ConsumerData, StorageOperationStatus> getCredentials(String consumerName) {
+        Either<ConsumerData, StorageOperationStatus> result = null;
+        log.debug("retriving Credentials for: {}", consumerName);
+        Either<ConsumerData, TitanOperationStatus> getNode = titanGenericDao.getNode(GraphPropertiesDictionary.CONSUMER_NAME.getProperty(), consumerName, ConsumerData.class);
+        if (getNode.isRight()) {
+            TitanOperationStatus status = getNode.right().value();
+            log.error("Error returned after get Consumer Data node {}. status returned is {}", consumerName, status);
+            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            return result;
+        }
+        ConsumerData consumerData = getNode.left().value();
+        return Either.left(consumerData);
+    }
 
-	@Override
-	public Either<List<ConsumerData>, StorageOperationStatus> getAll() {
-		log.debug("retrieving all consumers");
-		return titanGenericDao.getByCriteria(NodeTypeEnum.ConsumerCredentials, Collections.emptyMap(), ConsumerData.class)
-				.right().map(DaoStatusConverter::convertTitanStatusToStorageStatus);
-	}
+    @Override
+    public Either<List<ConsumerData>, StorageOperationStatus> getAll() {
+        log.debug("retrieving all consumers");
+        return titanGenericDao.getByCriteria(NodeTypeEnum.ConsumerCredentials, Collections.emptyMap(), ConsumerData.class)
+                .right().map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+    }
 
-	@Override
-	public Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData) {
-		return createCredentials(consumerData, false);
-	}
+    @Override
+    public Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData) {
+        return createCredentials(consumerData, false);
+    }
 
-	@Override
-	public Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData, boolean inTransaction) {
-		Either<ConsumerData, StorageOperationStatus> result = null;
-		try {
-			log.debug("creating Credentials for: {}", consumerData.getUniqueId());
-			Either<ConsumerData, TitanOperationStatus> createNode = titanGenericDao.createNode(consumerData, ConsumerData.class);
-			if (createNode.isRight()) {
-				TitanOperationStatus status = createNode.right().value();
-				log.error("Error returned after creating Consumer Data node {}. status returned is {}", consumerData.getUniqueId(), status);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-				return result;
-			}
-			ConsumerData createdConsumerData = createNode.left().value();
-			result = Either.left(createdConsumerData);
-			return result;
-		} finally {
-			handleTransaction(inTransaction, result);
-		}
-	}
+    @Override
+    public Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData, boolean inTransaction) {
+        Either<ConsumerData, StorageOperationStatus> result = null;
+        try {
+            log.debug("creating Credentials for: {}", consumerData.getUniqueId());
+            Either<ConsumerData, TitanOperationStatus> createNode = titanGenericDao.createNode(consumerData, ConsumerData.class);
+            if (createNode.isRight()) {
+                TitanOperationStatus status = createNode.right().value();
+                log.error("Error returned after creating Consumer Data node {}. status returned is {}", consumerData.getUniqueId(), status);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+                return result;
+            }
+            ConsumerData createdConsumerData = createNode.left().value();
+            result = Either.left(createdConsumerData);
+            return result;
+        } finally {
+            handleTransaction(inTransaction, result);
+        }
+    }
 
-	@Override
-	public Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName) {
-		return deleteCredentials(consumerName, false);
-	}
+    @Override
+    public Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName) {
+        return deleteCredentials(consumerName, false);
+    }
 
-	@Override
-	public Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName, boolean inTransaction) {
-		Either<ConsumerData, StorageOperationStatus> result = null;
-		try {
-			log.debug("delete Credentials for: {}", consumerName);
-			Either<ConsumerData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(GraphPropertiesDictionary.CONSUMER_NAME.getProperty(), consumerName, ConsumerData.class);
-			if (deleteNode.isRight()) {
-				TitanOperationStatus status = deleteNode.right().value();
-				log.error("Error returned after delete Consumer Data node {}. status returned is {}", consumerName, status);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-				return result;
-			}
+    @Override
+    public Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName, boolean inTransaction) {
+        Either<ConsumerData, StorageOperationStatus> result = null;
+        try {
+            log.debug("delete Credentials for: {}", consumerName);
+            Either<ConsumerData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(GraphPropertiesDictionary.CONSUMER_NAME.getProperty(), consumerName, ConsumerData.class);
+            if (deleteNode.isRight()) {
+                TitanOperationStatus status = deleteNode.right().value();
+                log.error("Error returned after delete Consumer Data node {}. status returned is {}", consumerName, status);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+                return result;
+            }
 
-			ConsumerData deletedConsumerData = deleteNode.left().value();
-			result = Either.left(deletedConsumerData);
-			return result;
-		} finally {
-			handleTransaction(inTransaction, result);
-		}
+            ConsumerData deletedConsumerData = deleteNode.left().value();
+            result = Either.left(deletedConsumerData);
+            return result;
+        } finally {
+            handleTransaction(inTransaction, result);
+        }
 
-	}
+    }
 
-	@Override
-	public Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData) {
-		return updateCredentials(consumerData, false);
-	}
+    @Override
+    public Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData) {
+        return updateCredentials(consumerData, false);
+    }
 
-	@Override
-	public Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData, boolean inTransaction) {
+    @Override
+    public Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData, boolean inTransaction) {
 
-		Either<ConsumerData, StorageOperationStatus> result = null;
-		try {
-			log.debug("update Credentials for: {}", consumerData.getUniqueId());
-			Either<ConsumerData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(consumerData, ConsumerData.class);
-			if (updateNode.isRight()) {
-				TitanOperationStatus status = updateNode.right().value();
-				log.error("Error returned after delete Consumer Data node {}. status returned is {}", consumerData.getUniqueId(), status);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-				return result;
-			}
-			ConsumerData updatedConsumerData = updateNode.left().value();
-			result = Either.left(updatedConsumerData);
-			return result;
-		} finally {
-			handleTransaction(inTransaction, result);
-		}
-	}
+        Either<ConsumerData, StorageOperationStatus> result = null;
+        try {
+            log.debug("update Credentials for: {}", consumerData.getUniqueId());
+            Either<ConsumerData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(consumerData, ConsumerData.class);
+            if (updateNode.isRight()) {
+                TitanOperationStatus status = updateNode.right().value();
+                log.error("Error returned after delete Consumer Data node {}. status returned is {}", consumerData.getUniqueId(), status);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+                return result;
+            }
+            ConsumerData updatedConsumerData = updateNode.left().value();
+            result = Either.left(updatedConsumerData);
+            return result;
+        } finally {
+            handleTransaction(inTransaction, result);
+        }
+    }
 
-	private void handleTransaction(boolean inTransaction, Either<ConsumerData, StorageOperationStatus> result) {
-		if (false == inTransaction) {
-			if (result == null || result.isRight()) {
-				log.error("Going to execute rollback on graph.");
-				titanGenericDao.rollback();
-			} else {
-				log.debug("Going to execute commit on graph.");
-				titanGenericDao.commit();
-			}
-		}
-	}
+    private void handleTransaction(boolean inTransaction, Either<ConsumerData, StorageOperationStatus> result) {
+        if (!inTransaction) {
+            if (result == null || result.isRight()) {
+                log.error("Going to execute rollback on graph.");
+                titanGenericDao.rollback();
+            } else {
+                log.debug("Going to execute commit on graph.");
+                titanGenericDao.commit();
+            }
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java
index 88edb1f..9ae2f25 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java
@@ -20,134 +20,130 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import fj.data.Either;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.openecomp.sdc.common.util.ZipUtil;
+
+import javax.annotation.PostConstruct;
 import java.io.File;
 import java.io.FileFilter;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.util.Map;
 
-import javax.annotation.PostConstruct;
-
-import org.apache.commons.io.filefilter.WildcardFileFilter;
-import org.openecomp.sdc.be.model.User;
-import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
-import org.openecomp.sdc.common.util.ZipUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-
-import fj.data.Either;
-
 @org.springframework.stereotype.Component("csar-operation")
 public class CsarOperation {
 
-	private static Logger log = LoggerFactory.getLogger(CsarOperation.class.getName());
+    private static final Logger log = Logger.getLogger(CsarOperation.class.getName());
 
-	@javax.annotation.Resource
-	private OnboardingClient onboardingClient;
+    @javax.annotation.Resource
+    private OnboardingClient onboardingClient;
 
-	public static void main(String[] args) {
+    public static void main(String[] args) {
 
-		CsarOperation csarOperation = new CsarOperation();
-		csarOperation.init();
+        CsarOperation csarOperation = new CsarOperation();
+        csarOperation.init();
 
-		String csarUuid = "70025CF6081B489CA7B1CBA583D5278D";
-		Either<Map<String, byte[]>, StorageOperationStatus> csar = csarOperation.getCsar(csarUuid, null);
-		System.out.println(csar.left().value());
+        String csarUuid = "70025CF6081B489CA7B1CBA583D5278D";
+        Either<Map<String, byte[]>, StorageOperationStatus> csar = csarOperation.getCsar(csarUuid, null);
+        System.out.println(csar.left().value());
 
-	}
+    }
 
-	@PostConstruct
-	public void init() {
+    @PostConstruct
+    public void init() {
 
-	}
+    }
 
-	public Either<Map<String, byte[]>, StorageOperationStatus> getMockCsar(String csarUuid) {
-		File dir = new File("/var/tmp/mockCsar");
-		FileFilter fileFilter = new WildcardFileFilter("*.csar");
-		File[] files = dir.listFiles(fileFilter);
-		for (int i = 0; i < files.length; i++) {
-			File csar = files[i];
-			if (csar.getName().startsWith(csarUuid)) {
-				log.debug("Found CSAR file {} matching the passed csarUuid {}", csar.getAbsolutePath(), csarUuid);
-				byte[] data;
-				try {
-					data = Files.readAllBytes(csar.toPath());
-				} catch (IOException e) {
-					log.debug("Error reading mock file for CSAR, error: {}", e);
-					return Either.right(StorageOperationStatus.NOT_FOUND);
-				}
-				Map<String, byte[]> readZip = ZipUtil.readZip(data);
-				return Either.left(readZip);
-			}
-		}
-		log.debug("Couldn't find mock file for CSAR starting with {}", csarUuid);
-		return Either.right(StorageOperationStatus.CSAR_NOT_FOUND);
-	}
+    public Either<Map<String, byte[]>, StorageOperationStatus> getMockCsar(String csarUuid) {
+        File dir = new File("/var/tmp/mockCsar");
+        FileFilter fileFilter = new WildcardFileFilter("*.csar");
+        File[] files = dir.listFiles(fileFilter);
+        for (int i = 0; i < files.length; i++) {
+            File csar = files[i];
+            if (csar.getName().startsWith(csarUuid)) {
+                log.debug("Found CSAR file {} matching the passed csarUuid {}", csar.getAbsolutePath(), csarUuid);
+                byte[] data;
+                try {
+                    data = Files.readAllBytes(csar.toPath());
+                } catch (IOException e) {
+                    log.debug("Error reading mock file for CSAR, error: {}", e);
+                    return Either.right(StorageOperationStatus.NOT_FOUND);
+                }
+                Map<String, byte[]> readZip = ZipUtil.readZip(data);
+                return Either.left(readZip);
+            }
+        }
+        log.debug("Couldn't find mock file for CSAR starting with {}", csarUuid);
+        return Either.right(StorageOperationStatus.CSAR_NOT_FOUND);
+    }
 
-	/**
-	 * get csar from remote repository
-	 * 
-	 * @param csarUuid
-	 * @return
-	 */
-	public Either<Map<String, byte[]>, StorageOperationStatus> getCsar(String csarUuid, User user) {
+    /**
+     * get csar from remote repository
+     *
+     * @param csarUuid
+     * @return
+     */
+    public Either<Map<String, byte[]>, StorageOperationStatus> getCsar(String csarUuid, User user) {
 
-		Either<Map<String, byte[]>, StorageOperationStatus> result = onboardingClient.getCsar(csarUuid, user.getUserId());
+        Either<Map<String, byte[]>, StorageOperationStatus> result = onboardingClient.getCsar(csarUuid, user.getUserId());
 
-		if (result.isRight()) {
-			log.debug("Cannot find csar {}. Staus returned is {}", csarUuid, result.right().value());
-		} else {
-			Map<String, byte[]> values = result.left().value();
-			if (values != null) {
-				log.debug("The returned files are {}", values.keySet());
-			}
-		}
+        if (result.isRight()) {
+            log.debug("Cannot find csar {}. Staus returned is {}", csarUuid, result.right().value());
+        } else {
+            Map<String, byte[]> values = result.left().value();
+            if (values != null) {
+                log.debug("The returned files are {}", values.keySet());
+            }
+        }
 
-		return result;
-	}
-	
-	@SuppressWarnings("unchecked")
-	public Either<String, StorageOperationStatus> getCsarLatestVersion(String csarUuid, User user) {
+        return result;
+    }
 
-		Either<String, StorageOperationStatus> result = onboardingClient.getPackages(user.getUserId());
+    @SuppressWarnings("unchecked")
+    public Either<String, StorageOperationStatus> getCsarLatestVersion(String csarUuid, User user) {
 
-		if (result.isRight()) {
-			log.debug("Cannot find version for package with Id {}. Status returned is {}", csarUuid, result.right().value());
-		} else {
-			String latestVersion = null;
-			JsonElement root = new JsonParser().parse(result.left().value());
-			JsonArray csarsInfo = root.getAsJsonObject().get("results").getAsJsonArray();
-			for (JsonElement csarInfo : csarsInfo) {
-				Map<String, String> csarInfoMap = new Gson().fromJson(csarInfo, Map.class);
-				if(csarInfoMap.get("packageId").equals(csarUuid)){
-				    String curVersion = csarInfoMap.get("version");
-				    if(latestVersion == null || isGreater(latestVersion, curVersion)){
-				    	latestVersion = curVersion;
-				    }
-				}
-			}
-			if (latestVersion != null) {
-				result = Either.left(latestVersion);
-			} else {
-				log.debug("The returned packages are {}. Failed to find latest version for package with Id {}. ", result.left().value(), csarUuid);
-				result = Either.right(StorageOperationStatus.NOT_FOUND);
-			}
-		}
+        Either<String, StorageOperationStatus> result = onboardingClient.getPackages(user.getUserId());
 
-		return result;
-	}
+        if (result.isRight()) {
+            log.debug("Cannot find version for package with Id {}. Status returned is {}", csarUuid, result.right().value());
+        } else {
+            String latestVersion = null;
+            JsonElement root = new JsonParser().parse(result.left().value());
+            JsonArray csarsInfo = root.getAsJsonObject().get("results").getAsJsonArray();
+            for (JsonElement csarInfo : csarsInfo) {
+                Map<String, String> csarInfoMap = new Gson().fromJson(csarInfo, Map.class);
+                if(csarInfoMap.get("packageId").equals(csarUuid)){
+                    String curVersion = csarInfoMap.get("version");
+                    if(latestVersion == null || isGreater(latestVersion, curVersion)){
+                        latestVersion = curVersion;
+                    }
+                }
+            }
+            if (latestVersion != null) {
+                result = Either.left(latestVersion);
+            } else {
+                log.debug("The returned packages are {}. Failed to find latest version for package with Id {}. ", result.left().value(), csarUuid);
+                result = Either.right(StorageOperationStatus.NOT_FOUND);
+            }
+        }
 
-	private boolean isGreater(String latestVersion, String currentVersion) {
-		return Double.parseDouble(latestVersion) < Double.parseDouble(currentVersion);
-	}
+        return result;
+    }
 
-	public OnboardingClient getOnboardingClient() {
-		return onboardingClient;
-	}
+    private boolean isGreater(String latestVersion, String currentVersion) {
+        return Double.parseDouble(latestVersion) < Double.parseDouble(currentVersion);
+    }
+
+    public OnboardingClient getOnboardingClient() {
+        return onboardingClient;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.java
index 3bda116..a66dce1 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.java
@@ -20,98 +20,78 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import org.openecomp.sdc.be.dao.api.ResourceUploadStatus;
 import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 
 public class DaoStatusConverter {
 
-	public static StorageOperationStatus convertTitanStatusToStorageStatus(TitanOperationStatus titanStatus) {
+    public static StorageOperationStatus convertTitanStatusToStorageStatus(TitanOperationStatus titanStatus) {
 
-		if (titanStatus == null) {
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
+        if (titanStatus == null) {
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
 
-		switch (titanStatus) {
+        switch (titanStatus) {
 
-		case OK:
-			return StorageOperationStatus.OK;
+        case OK:
+            return StorageOperationStatus.OK;
 
-		case NOT_CONNECTED:
-			return StorageOperationStatus.CONNECTION_FAILURE;
+        case NOT_CONNECTED:
+            return StorageOperationStatus.CONNECTION_FAILURE;
 
-		case NOT_FOUND:
-			return StorageOperationStatus.NOT_FOUND;
+        case NOT_FOUND:
+            return StorageOperationStatus.NOT_FOUND;
 
-		case NOT_CREATED:
-			return StorageOperationStatus.SCHEMA_ERROR;
+        case NOT_CREATED:
+            return StorageOperationStatus.SCHEMA_ERROR;
 
-		case INDEX_CANNOT_BE_CHANGED:
-			return StorageOperationStatus.SCHEMA_ERROR;
+        case INDEX_CANNOT_BE_CHANGED:
+            return StorageOperationStatus.SCHEMA_ERROR;
 
-		case MISSING_UNIQUE_ID:
-			return StorageOperationStatus.BAD_REQUEST;
-		case ALREADY_LOCKED:
-			return StorageOperationStatus.FAILED_TO_LOCK_ELEMENT;
+        case MISSING_UNIQUE_ID:
+            return StorageOperationStatus.BAD_REQUEST;
+        case ALREADY_LOCKED:
+            return StorageOperationStatus.FAILED_TO_LOCK_ELEMENT;
 
-		case TITAN_SCHEMA_VIOLATION:
-			return StorageOperationStatus.SCHEMA_VIOLATION;
+        case TITAN_SCHEMA_VIOLATION:
+            return StorageOperationStatus.SCHEMA_VIOLATION;
 
-		case INVALID_ID:
-			return StorageOperationStatus.INVALID_ID;
-		case MATCH_NOT_FOUND:
-			return StorageOperationStatus.MATCH_NOT_FOUND;
+        case INVALID_ID:
+            return StorageOperationStatus.INVALID_ID;
+        case MATCH_NOT_FOUND:
+            return StorageOperationStatus.MATCH_NOT_FOUND;
 
-		case ILLEGAL_ARGUMENT:
-			return StorageOperationStatus.BAD_REQUEST;
-		case ALREADY_EXIST:
-			return StorageOperationStatus.ENTITY_ALREADY_EXISTS;
-		case PROPERTY_NAME_ALREADY_EXISTS:
-			return StorageOperationStatus.PROPERTY_NAME_ALREADY_EXISTS;
-		case INVALID_PROPERTY:
-			return StorageOperationStatus.INVALID_PROPERTY;
-		default:
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
+        case ILLEGAL_ARGUMENT:
+            return StorageOperationStatus.BAD_REQUEST;
+        case ALREADY_EXIST:
+            return StorageOperationStatus.ENTITY_ALREADY_EXISTS;
+        case PROPERTY_NAME_ALREADY_EXISTS:
+            return StorageOperationStatus.PROPERTY_NAME_ALREADY_EXISTS;
+        case INVALID_PROPERTY:
+            return StorageOperationStatus.INVALID_PROPERTY;
+        default:
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
 
-	}
+    }
 
-	public static StorageOperationStatus convertRsrcUploadStatusToStorageStatus(ResourceUploadStatus resourceUploadStatus) {
-		if (resourceUploadStatus == null) {
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
-		switch (resourceUploadStatus) {
-		case OK:
-			return StorageOperationStatus.OK;
-		case ALREADY_EXIST:
-			return StorageOperationStatus.ENTITY_ALREADY_EXISTS;
-		case NOT_EXIST:
-			return StorageOperationStatus.ARTIFACT_NOT_FOUND;
-		case SERVICE_NOT_EXIST:
-		case COMPONENT_NOT_EXIST:
-			return StorageOperationStatus.NOT_FOUND;
-		default:
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
-	}
+    public static StorageOperationStatus convertCassandraStatusToStorageStatus(CassandraOperationStatus status) {
+        if (status == null) {
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+        switch (status) {
+        case OK:
+            return StorageOperationStatus.OK;
+        case CLUSTER_NOT_CONNECTED:
+            return StorageOperationStatus.CONNECTION_FAILURE;
+        case KEYSPACE_NOT_CONNECTED:
+            return StorageOperationStatus.STORAGE_NOT_AVAILABLE;
+        case NOT_FOUND:
+            return StorageOperationStatus.NOT_FOUND;
 
-	public static StorageOperationStatus convertCassandraStatusToStorageStatus(CassandraOperationStatus status) {
-		if (status == null) {
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
-		switch (status) {
-		case OK:
-			return StorageOperationStatus.OK;
-		case CLUSTER_NOT_CONNECTED:
-			return StorageOperationStatus.CONNECTION_FAILURE;
-		case KEYSPACE_NOT_CONNECTED:
-			return StorageOperationStatus.STORAGE_NOT_AVAILABLE;
-		case NOT_FOUND:
-			return StorageOperationStatus.NOT_FOUND;
-
-		default:
-			return StorageOperationStatus.GENERAL_ERROR;
-		}
-	}
+        default:
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DefaultDerivedFromOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DefaultDerivedFromOperation.java
index 2e5da8d..6f95558 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DefaultDerivedFromOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DefaultDerivedFromOperation.java
@@ -1,25 +1,29 @@
 package org.openecomp.sdc.be.model.operations.impl;
 
+import fj.data.Either;
+import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
+import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.resources.data.UniqueIdData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
-import fj.data.Either;
+import java.util.*;
+import java.util.function.Function;
 
 @Component
 public class DefaultDerivedFromOperation implements DerivedFromOperation {
 
-    private static final Logger log = LoggerFactory.getLogger(DefaultDerivedFromOperation.class);
+    private static final Logger log = Logger.getLogger(DefaultDerivedFromOperation.class.getName());
     private TitanGenericDao titanGenericDao;
 
     public DefaultDerivedFromOperation(TitanGenericDao titanGenericDao) {
@@ -28,8 +32,8 @@
 
     @Override
     public Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(String parentUniqueId, String derivedFromUniqueId, NodeTypeEnum nodeType) {
-        UniqueIdData from = new UniqueIdData(NodeTypeEnum.PolicyType, parentUniqueId);
-        UniqueIdData to = new UniqueIdData(NodeTypeEnum.PolicyType, derivedFromUniqueId);
+        UniqueIdData from = new UniqueIdData(nodeType, parentUniqueId);
+        UniqueIdData to = new UniqueIdData(nodeType, derivedFromUniqueId);
         return titanGenericDao.createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null)
                 .right()
                 .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
@@ -45,8 +49,8 @@
 
     @Override
     public StorageOperationStatus removeDerivedFromRelation(String uniqueId, String derivedFromUniqueId, NodeTypeEnum nodeType) {
-        UniqueIdData from = new UniqueIdData(NodeTypeEnum.PolicyType, uniqueId);
-        UniqueIdData to = new UniqueIdData(NodeTypeEnum.PolicyType, derivedFromUniqueId);
+        UniqueIdData from = new UniqueIdData(nodeType, uniqueId);
+        UniqueIdData to = new UniqueIdData(nodeType, derivedFromUniqueId);
         return isDerivedFromExists(from, to)
                 .either(isRelationExist -> isRelationExist ? deleteDerivedFrom(from, to) : StorageOperationStatus.OK,
                         DaoStatusConverter::convertTitanStatusToStorageStatus);
@@ -63,6 +67,90 @@
     private Either<Boolean, TitanOperationStatus> isDerivedFromExists(UniqueIdData from, UniqueIdData to) {
         return titanGenericDao.isRelationExist(from, to, GraphEdgeLabels.DERIVED_FROM);
     }
-
+    
+    @Override
+    public <T extends GraphNode> Either<Boolean, StorageOperationStatus> isTypeDerivedFrom(String childCandidateType, String parentCandidateType, String currentChildType, 
+                                                                                                    NodeTypeEnum nodeType, Class<T> clazz, Function<T, String> typeProvider) {
+        Map<String, Object> propertiesToMatch = new HashMap<>();
+        propertiesToMatch.put(GraphPropertiesDictionary.TYPE.getProperty(), childCandidateType);
+        
+        Either<List<T>, TitanOperationStatus> getResponse = titanGenericDao.getByCriteria(nodeType, propertiesToMatch, clazz);
+        if (getResponse.isRight()) {
+            TitanOperationStatus titanOperationStatus = getResponse.right().value();
+            log.debug("Couldn't fetch type {}, error: {}", childCandidateType, titanOperationStatus);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus));
+        }
+        T node = getResponse.left().value().get(0);
+        String childUniqueId = node.getUniqueId();
+        String childType = typeProvider.apply(node);
+        
+        Set<String> travelledTypes = new HashSet<>();
+        if (currentChildType != null) {
+            travelledTypes.add(currentChildType);
+        }
+        
+        do {
+            travelledTypes.add(childType);
+            Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), childUniqueId, GraphEdgeLabels.DERIVED_FROM,
+                    nodeType, clazz);
+            if (childrenNodes.isRight()) {
+                if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) {
+                    TitanOperationStatus titanOperationStatus = getResponse.right().value();
+                    log.debug("Couldn't fetch derived from node for type {}, error: {}", childCandidateType, titanOperationStatus);
+                    return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus));
+                } else {
+                    log.debug("Derived from node is not found for type {} - this is OK for root capability.", childCandidateType);
+                    return Either.left(false);
+                }
+            }
+            String derivedFromUniqueId = childrenNodes.left().value().get(0).getLeft().getUniqueId();
+            String derivedFromType = typeProvider.apply(childrenNodes.left().value().get(0).getLeft());
+            if (derivedFromType.equals(parentCandidateType)) {
+                log.debug("Verified that type {} derives from type {}", childCandidateType, parentCandidateType);
+                return Either.left(true);
+            }
+            childUniqueId = derivedFromUniqueId;
+            childType = derivedFromType;
+        } while (!travelledTypes.contains(childType));
+        // this stop condition should never be used, if we use it, we have an
+        // illegal cycle in graph - "derived from" hierarchy cannot be cycled.
+        // It's here just to avoid infinite loop in case we have such cycle.
+        log.error("Detected a cycle of \"derived from\" edges starting at type node {}", childType);
+        return Either.right(StorageOperationStatus.GENERAL_ERROR);
+    }
+    
+    
+    
+    @Override
+    public <T extends GraphNode> StorageOperationStatus isUpdateParentAllowed(String oldTypeParent, String newTypeParent, String childType,
+                                                                              NodeTypeEnum nodeType, Class<T> clazz,
+                                                                              Function<T, String> typeProvider) {
+        StorageOperationStatus status;
+        if (oldTypeParent != null) {
+            
+            Either<Boolean, StorageOperationStatus> result = isTypeDerivedFrom(newTypeParent, oldTypeParent, childType, nodeType, clazz, typeProvider);
+            if (result.isRight()) {
+                log.debug("#isUpdateParentAllowed - failed to detect that new parent {} is derived from the current parent {}",  newTypeParent, oldTypeParent);
+                status = result.right().value();
+            }
+            else {
+                if (result.left().value()) {
+                    log.debug("#isUpdateParentAllowed - update is allowed since new parent {} is derived from the current parent {}",  newTypeParent, oldTypeParent);
+                    status = StorageOperationStatus.OK;
+                }
+                else {
+                    log.debug("#isUpdateParentAllowed - update is not allowed since new parent {} is not derived from the current parent {}",  newTypeParent, oldTypeParent);
+                    status = StorageOperationStatus.CANNOT_UPDATE_EXISTING_ENTITY;
+                }
+            }
+                        
+        }
+        else {
+            log.debug("#isUpdateParentAllowed - the update is allowed since the parent still has been not set." );
+            status = StorageOperationStatus.OK;
+        }
+        
+        return status;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java
index 41f6ce9..fd455bc 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java
@@ -20,12 +20,9 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.openecomp.sdc.be.config.Configuration.ArtifactTypeConfig;
@@ -55,776 +52,773 @@
 import org.openecomp.sdc.be.resources.data.category.CategoryData;
 import org.openecomp.sdc.be.resources.data.category.GroupingData;
 import org.openecomp.sdc.be.resources.data.category.SubCategoryData;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
 
-import com.thinkaurelius.titan.core.TitanGraph;
-//import com.tinkerpop.blueprints.Vertex;
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.util.*;
 
 @Component("element-operation")
 public class ElementOperation implements IElementOperation {
 
+    private static final String COULDN_T_FETCH_TITAN_GRAPH = "Couldn't fetch titan graph";
+	private static final String UNKNOWN_CATEGORY_TYPE = "Unknown category type {}";
 	private TitanGenericDao titanGenericDao;
 
-	public ElementOperation(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao) {
-		super();
-		this.titanGenericDao = titanGenericDao;
-	}
+    public ElementOperation(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao) {
+        super();
+        this.titanGenericDao = titanGenericDao;
+    }
 
-	private static Logger log = LoggerFactory.getLogger(ElementOperation.class.getName());
+    private static final Logger log = Logger.getLogger(ElementOperation.class.getName());
 
-	/*
-	 * Old flow
-	 */
-	@Override
-	public Either<List<CategoryDefinition>, ActionStatus> getAllServiceCategories() {
-		return getAllCategories(NodeTypeEnum.ServiceNewCategory, false);
-	}
+    /*
+     * Old flow
+     */
+    @Override
+    public Either<List<CategoryDefinition>, ActionStatus> getAllServiceCategories() {
+        return getAllCategories(NodeTypeEnum.ServiceNewCategory, false);
+    }
 
-	@Override
-	public Either<List<CategoryDefinition>, ActionStatus> getAllResourceCategories() {
-		return getAllCategories(NodeTypeEnum.ResourceNewCategory, false);
-	}
+    @Override
+    public Either<List<CategoryDefinition>, ActionStatus> getAllResourceCategories() {
+        return getAllCategories(NodeTypeEnum.ResourceNewCategory, false);
+    }
 
-	@Override
-	public Either<List<CategoryDefinition>, ActionStatus> getAllProductCategories() {
-		return getAllCategories(NodeTypeEnum.ProductCategory, false);
-	}
-	/*
-	 * 
-	 */
+    @Override
+    public Either<List<CategoryDefinition>, ActionStatus> getAllProductCategories() {
+        return getAllCategories(NodeTypeEnum.ProductCategory, false);
+    }
+    /*
+     *
+     */
 
-	/*
-	 * New flow
-	 */
-	@Override
-	public Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType) {
-		return createCategory(category, nodeType, false);
-	}
+    /*
+     * New flow
+     */
+    @Override
+    public Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType) {
+        return createCategory(category, nodeType, false);
+    }
 
-	@Override
-	public Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType, boolean inTransaction) {
-		Either<CategoryDefinition, ActionStatus> result = null;
-		category.setUniqueId(UniqueIdBuilder.buildCategoryUid(category.getNormalizedName(), nodeType));
-		CategoryData categoryData = new CategoryData(nodeType, category);
+    @Override
+    public Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType, boolean inTransaction) {
+        Either<CategoryDefinition, ActionStatus> result = null;
+        category.setUniqueId(UniqueIdBuilder.buildCategoryUid(category.getNormalizedName(), nodeType));
+        CategoryData categoryData = new CategoryData(nodeType, category);
 
-		try {
-			Either<CategoryData, TitanOperationStatus> createNode = titanGenericDao.createNode(categoryData, CategoryData.class);
-			if (createNode.isRight()) {
-				TitanOperationStatus value = createNode.right().value();
-				ActionStatus actionStatus = ActionStatus.GENERAL_ERROR;
-				log.debug("Problem while creating category, reason {}", value);
-				if (value == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) {
-					actionStatus = ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS;
-				}
-				result = Either.right(actionStatus);
-				return result;
-			}
-			CategoryDefinition created = new CategoryDefinition(createNode.left().value().getCategoryDataDefinition());
-			result = Either.left(created);
-			return result;
-		} finally {
-			if (inTransaction == false) {
-				if (result != null && result.isLeft()) {
-					titanGenericDao.commit();
-				} else {
-					titanGenericDao.rollback();
-				}
-			}
-		}
-	}
+        try {
+            Either<CategoryData, TitanOperationStatus> createNode = titanGenericDao.createNode(categoryData, CategoryData.class);
+            if (createNode.isRight()) {
+                TitanOperationStatus value = createNode.right().value();
+                ActionStatus actionStatus = ActionStatus.GENERAL_ERROR;
+                log.debug("Problem while creating category, reason {}", value);
+                if (value == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) {
+                    actionStatus = ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS;
+                }
+                result = Either.right(actionStatus);
+                return result;
+            }
+            CategoryDefinition created = new CategoryDefinition(createNode.left().value().getCategoryDataDefinition());
+            result = Either.left(created);
+            return result;
+        } finally {
+            if (!inTransaction) {
+                if (result != null && result.isLeft()) {
+                    titanGenericDao.commit();
+                } else {
+                    titanGenericDao.rollback();
+                }
+            }
+        }
+    }
 
-	@Override
-	public Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, NodeTypeEnum nodeType) {
-		return createSubCategory(categoryId, subCategory, nodeType, false);
-	}
+    @Override
+    public Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, NodeTypeEnum nodeType) {
+        return createSubCategory(categoryId, subCategory, nodeType, false);
+    }
 
-	@Override
-	public Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, NodeTypeEnum nodeType, boolean inTransaction) {
+    @Override
+    public Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, NodeTypeEnum nodeType, boolean inTransaction) {
 
-		Either<SubCategoryDefinition, ActionStatus> result = null;
+        Either<SubCategoryDefinition, ActionStatus> result = null;
 
-		try {
-			// create edge from category to sub-category
-			Either<CategoryData, TitanOperationStatus> categoryNode = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class);
-			ActionStatus actionStatus = ActionStatus.GENERAL_ERROR;
-			if (categoryNode.isRight()) {
-				TitanOperationStatus titanOperationStatus = categoryNode.right().value();
-				log.debug("Problem while fetching category, reason {}", titanOperationStatus);
-				if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
-					actionStatus = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND;
-				}
-				result = Either.right(actionStatus);
-				return result;
-			}
+        try {
+            // create edge from category to sub-category
+            Either<CategoryData, TitanOperationStatus> categoryNode = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class);
+            ActionStatus actionStatus = ActionStatus.GENERAL_ERROR;
+            if (categoryNode.isRight()) {
+                TitanOperationStatus titanOperationStatus = categoryNode.right().value();
+                log.debug("Problem while fetching category, reason {}", titanOperationStatus);
+                if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
+                    actionStatus = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND;
+                }
+                result = Either.right(actionStatus);
+                return result;
+            }
 
-			CategoryDataDefinition categoryDataDefinition = categoryNode.left().value().getCategoryDataDefinition();
-			subCategory.setUniqueId(UniqueIdBuilder.buildSubCategoryUid(categoryDataDefinition.getUniqueId(), subCategory.getNormalizedName()));
-			SubCategoryData subCategoryData = new SubCategoryData(nodeType, subCategory);
+            CategoryDataDefinition categoryDataDefinition = categoryNode.left().value().getCategoryDataDefinition();
+            subCategory.setUniqueId(UniqueIdBuilder.buildSubCategoryUid(categoryDataDefinition.getUniqueId(), subCategory.getNormalizedName()));
+            SubCategoryData subCategoryData = new SubCategoryData(nodeType, subCategory);
 
-			Either<SubCategoryData, TitanOperationStatus> subCategoryNode = titanGenericDao.createNode(subCategoryData, SubCategoryData.class);
-			if (subCategoryNode.isRight()) {
-				TitanOperationStatus titanOperationStatus = subCategoryNode.right().value();
-				log.debug("Problem while creating category, reason {}", titanOperationStatus);
-				if (titanOperationStatus == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) {
-					actionStatus = ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY;
-				}
-				result = Either.right(actionStatus);
-				return result;
-			}
+            Either<SubCategoryData, TitanOperationStatus> subCategoryNode = titanGenericDao.createNode(subCategoryData, SubCategoryData.class);
+            if (subCategoryNode.isRight()) {
+                TitanOperationStatus titanOperationStatus = subCategoryNode.right().value();
+                log.debug("Problem while creating category, reason {}", titanOperationStatus);
+                if (titanOperationStatus == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) {
+                    actionStatus = ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY;
+                }
+                result = Either.right(actionStatus);
+                return result;
+            }
 
-			Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation(categoryNode.left().value(), subCategoryNode.left().value(), GraphEdgeLabels.SUB_CATEGORY, null);
-			if (relation.isRight()) {
-				log.debug("Problem while create relation between category and sub-category ", relation.right().value());
-				result = Either.right(actionStatus);
-				return result;
-			}
-			SubCategoryDefinition subCategoryCreated = new SubCategoryDefinition(subCategoryNode.left().value().getSubCategoryDataDefinition());
-			result = Either.left(subCategoryCreated);
-			return result;
-		} finally {
-			if (inTransaction == false) {
-				if (result != null && result.isLeft()) {
-					titanGenericDao.commit();
-				} else {
-					titanGenericDao.rollback();
-				}
-			}
-		}
-	}
+            Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation(categoryNode.left().value(), subCategoryNode.left().value(), GraphEdgeLabels.SUB_CATEGORY, null);
+            if (relation.isRight()) {
+                log.debug("Problem while create relation between category and sub-category ", relation.right().value());
+                result = Either.right(actionStatus);
+                return result;
+            }
+            SubCategoryDefinition subCategoryCreated = new SubCategoryDefinition(subCategoryNode.left().value().getSubCategoryDataDefinition());
+            result = Either.left(subCategoryCreated);
+            return result;
+        } finally {
+            if (!inTransaction) {
+                if (result != null && result.isLeft()) {
+                    titanGenericDao.commit();
+                } else {
+                    titanGenericDao.rollback();
+                }
+            }
+        }
+    }
 
-	@Override
-	public Either<GroupingDefinition, ActionStatus> createGrouping(String subCategoryId, GroupingDefinition grouping, NodeTypeEnum nodeType) {
+    @Override
+    public Either<GroupingDefinition, ActionStatus> createGrouping(String subCategoryId, GroupingDefinition grouping, NodeTypeEnum nodeType) {
 
-		Either<GroupingDefinition, ActionStatus> result = null;
+        Either<GroupingDefinition, ActionStatus> result = null;
 
-		try {
-			// create edge from sub-category to grouping
-			Either<SubCategoryData, TitanOperationStatus> subCategoryNode = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
-			ActionStatus actionStatus = ActionStatus.GENERAL_ERROR;
-			if (subCategoryNode.isRight()) {
-				TitanOperationStatus titanOperationStatus = subCategoryNode.right().value();
-				log.debug("Problem while fetching category, reason {}", titanOperationStatus);
-				if (titanOperationStatus == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) {
-					actionStatus = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND;
-				}
-				result = Either.right(actionStatus);
-				return result;
-			}
+        try {
+            // create edge from sub-category to grouping
+            Either<SubCategoryData, TitanOperationStatus> subCategoryNode = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
+            ActionStatus actionStatus = ActionStatus.GENERAL_ERROR;
+            if (subCategoryNode.isRight()) {
+                TitanOperationStatus titanOperationStatus = subCategoryNode.right().value();
+                log.debug("Problem while fetching category, reason {}", titanOperationStatus);
+                if (titanOperationStatus == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) {
+                    actionStatus = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND;
+                }
+                result = Either.right(actionStatus);
+                return result;
+            }
 
-			SubCategoryDataDefinition subCatData = subCategoryNode.left().value().getSubCategoryDataDefinition();
-			grouping.setUniqueId(UniqueIdBuilder.buildGroupingUid(subCatData.getUniqueId(), grouping.getNormalizedName()));
-			GroupingData groupingData = new GroupingData(nodeType, grouping);
+            SubCategoryDataDefinition subCatData = subCategoryNode.left().value().getSubCategoryDataDefinition();
+            grouping.setUniqueId(UniqueIdBuilder.buildGroupingUid(subCatData.getUniqueId(), grouping.getNormalizedName()));
+            GroupingData groupingData = new GroupingData(nodeType, grouping);
 
-			Either<GroupingData, TitanOperationStatus> groupingNode = titanGenericDao.createNode(groupingData, GroupingData.class);
-			if (groupingNode.isRight()) {
-				TitanOperationStatus titanOperationStatus = groupingNode.right().value();
-				log.debug("Problem while creating grouping, reason {}", titanOperationStatus);
-				if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
-					actionStatus = ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY;
-				}
-				result = Either.right(actionStatus);
-				return result;
-			}
+            Either<GroupingData, TitanOperationStatus> groupingNode = titanGenericDao.createNode(groupingData, GroupingData.class);
+            if (groupingNode.isRight()) {
+                TitanOperationStatus titanOperationStatus = groupingNode.right().value();
+                log.debug("Problem while creating grouping, reason {}", titanOperationStatus);
+                if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
+                    actionStatus = ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY;
+                }
+                result = Either.right(actionStatus);
+                return result;
+            }
 
-			Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation(subCategoryNode.left().value(), groupingNode.left().value(), GraphEdgeLabels.GROUPING, null);
-			if (relation.isRight()) {
-				log.debug("Problem while create relation between sub-category and grouping", relation.right().value());
-				result = Either.right(actionStatus);
-				return result;
-			}
-			GroupingDefinition groupingCreated = new GroupingDefinition(groupingNode.left().value().getGroupingDataDefinition());
-			result = Either.left(groupingCreated);
-			return result;
-		} finally {
-			if (result != null && result.isLeft()) {
-				titanGenericDao.commit();
-			} else {
-				titanGenericDao.rollback();
-			}
-		}
-	}
+            Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation(subCategoryNode.left().value(), groupingNode.left().value(), GraphEdgeLabels.GROUPING, null);
+            if (relation.isRight()) {
+                log.debug("Problem while create relation between sub-category and grouping", relation.right().value());
+                result = Either.right(actionStatus);
+                return result;
+            }
+            GroupingDefinition groupingCreated = new GroupingDefinition(groupingNode.left().value().getGroupingDataDefinition());
+            result = Either.left(groupingCreated);
+            return result;
+        } finally {
+            if (result != null && result.isLeft()) {
+                titanGenericDao.commit();
+            } else {
+                titanGenericDao.rollback();
+            }
+        }
+    }
 
-	@Override
-	public Either<List<CategoryDefinition>, ActionStatus> getAllCategories(NodeTypeEnum nodeType, boolean inTransaction) {
-		try {
-			if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory && nodeType != NodeTypeEnum.ProductCategory) {
-				log.debug("Unknown category type {}", nodeType.name());
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
+    @Override
+    public Either<List<CategoryDefinition>, ActionStatus> getAllCategories(NodeTypeEnum nodeType, boolean inTransaction) {
+        try {
+            if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory && nodeType != NodeTypeEnum.ProductCategory) {
+                log.debug(UNKNOWN_CATEGORY_TYPE, nodeType.name());
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
 
-			Either<List<org.openecomp.sdc.be.resources.data.category.CategoryData>, TitanOperationStatus> either = titanGenericDao.getAll(nodeType, org.openecomp.sdc.be.resources.data.category.CategoryData.class);
-			if (either.isRight() && (either.right().value() != TitanOperationStatus.NOT_FOUND)) {
-				log.debug("Problem while get all categories. reason - {}", either.right().value());
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
-			List<CategoryData> categoryDataList = either.isLeft() ? either.left().value() : null;
-			List<CategoryDefinition> categoryList = new ArrayList<CategoryDefinition>();
-			if (categoryDataList != null) {
-				for (CategoryData elem : categoryDataList) {
-					CategoryDataDefinition categoryDataDefinition = elem.getCategoryDataDefinition();
+            Either<List<org.openecomp.sdc.be.resources.data.category.CategoryData>, TitanOperationStatus> either = titanGenericDao.getAll(nodeType, org.openecomp.sdc.be.resources.data.category.CategoryData.class);
+            if (either.isRight() && (either.right().value() != TitanOperationStatus.NOT_FOUND)) {
+                log.debug("Problem while get all categories. reason - {}", either.right().value());
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
+            List<CategoryData> categoryDataList = either.isLeft() ? either.left().value() : null;
+            List<CategoryDefinition> categoryList = new ArrayList<>();
+            if (categoryDataList != null) {
+                for (CategoryData elem : categoryDataList) {
+                    CategoryDataDefinition categoryDataDefinition = elem.getCategoryDataDefinition();
 
-					CategoryDefinition categoryDefinition = new CategoryDefinition(categoryDataDefinition);
-					String categoryName = categoryDataDefinition.getName();
-					log.trace("Found category {}, category type {}", categoryName, nodeType);
-					TitanOperationStatus setSubCategories = setSubCategories(nodeType, categoryDefinition);
-					if (setSubCategories != TitanOperationStatus.OK) {
-						log.debug("Failed to set sub-categories for category {}, category type {}, error {}", categoryName, nodeType, setSubCategories);
-						return Either.right(ActionStatus.GENERAL_ERROR);
-					}
-					categoryList.add(categoryDefinition);
-				}
-			}
-			return Either.left(categoryList);
-		} finally {
-			if (!inTransaction) {
-				titanGenericDao.commit();
-			}
-		}
-	}
+                    CategoryDefinition categoryDefinition = new CategoryDefinition(categoryDataDefinition);
+                    String categoryName = categoryDataDefinition.getName();
+                    log.trace("Found category {}, category type {}", categoryName, nodeType);
+                    TitanOperationStatus setSubCategories = setSubCategories(nodeType, categoryDefinition);
+                    if (setSubCategories != TitanOperationStatus.OK) {
+                        log.debug("Failed to set sub-categories for category {}, category type {}, error {}", categoryName, nodeType, setSubCategories);
+                        return Either.right(ActionStatus.GENERAL_ERROR);
+                    }
+                    categoryList.add(categoryDefinition);
+                }
+            }
+            return Either.left(categoryList);
+        } finally {
+            if (!inTransaction) {
+                titanGenericDao.commit();
+            }
+        }
+    }
 
-	private TitanOperationStatus setSubCategories(NodeTypeEnum parentNodeType, CategoryDefinition parentCategory) {
-		NodeTypeEnum childNodeType = getChildNodeType(parentNodeType);
-		if (childNodeType != null) {
-			String categoryName = parentCategory.getName();
-			log.trace("Getting sub-categories for category {}, category type {}", categoryName, parentNodeType);
-			Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, TitanOperationStatus> parentNode = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentCategory.getUniqueId(), GraphEdgeLabels.SUB_CATEGORY,
-					childNodeType, SubCategoryData.class);
-			if (parentNode.isRight()) {
-				TitanOperationStatus titanOperationStatus = parentNode.right().value();
-				if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
-					log.trace("Didn't find subcategories for category {}, category type {}", categoryName, parentNodeType);
-					titanOperationStatus = TitanOperationStatus.OK;
-				}
-				return titanOperationStatus;
-			}
-			List<ImmutablePair<SubCategoryData, GraphEdge>> subsCategoriesData = parentNode.left().value();
-			List<SubCategoryDefinition> subCategoriesDefinitions = new ArrayList<>();
-			for (ImmutablePair<SubCategoryData, GraphEdge> subCatPair : subsCategoriesData) {
-				SubCategoryDataDefinition subCategoryDataDefinition = subCatPair.getLeft().getSubCategoryDataDefinition();
-				SubCategoryDefinition subCategoryDefinition = new SubCategoryDefinition(subCategoryDataDefinition);
+    private TitanOperationStatus setSubCategories(NodeTypeEnum parentNodeType, CategoryDefinition parentCategory) {
+        NodeTypeEnum childNodeType = getChildNodeType(parentNodeType);
+        if (childNodeType != null) {
+            String categoryName = parentCategory.getName();
+            log.trace("Getting sub-categories for category {}, category type {}", categoryName, parentNodeType);
+            Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, TitanOperationStatus> parentNode = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentCategory.getUniqueId(), GraphEdgeLabels.SUB_CATEGORY,
+                    childNodeType, SubCategoryData.class);
+            if (parentNode.isRight()) {
+                TitanOperationStatus titanOperationStatus = parentNode.right().value();
+                if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
+                    log.trace("Didn't find subcategories for category {}, category type {}", categoryName, parentNodeType);
+                    titanOperationStatus = TitanOperationStatus.OK;
+                }
+                return titanOperationStatus;
+            }
+            List<ImmutablePair<SubCategoryData, GraphEdge>> subsCategoriesData = parentNode.left().value();
+            List<SubCategoryDefinition> subCategoriesDefinitions = new ArrayList<>();
+            for (ImmutablePair<SubCategoryData, GraphEdge> subCatPair : subsCategoriesData) {
+                SubCategoryDataDefinition subCategoryDataDefinition = subCatPair.getLeft().getSubCategoryDataDefinition();
+                SubCategoryDefinition subCategoryDefinition = new SubCategoryDefinition(subCategoryDataDefinition);
 
-				log.trace("Found sub-category {} for category {}, category type {}", subCategoryDataDefinition.getName(), categoryName, parentNodeType);
-				TitanOperationStatus setGroupings = setGroupings(childNodeType, subCategoryDefinition);
-				if (setGroupings != TitanOperationStatus.OK) {
-					log.debug("Failed to set groupings for sub-category {}, sub-category type {}, error {}", subCategoryDataDefinition.getName(), childNodeType, setGroupings);
-					return TitanOperationStatus.GENERAL_ERROR;
-				}
-				subCategoriesDefinitions.add(subCategoryDefinition);
-			}
-			parentCategory.setSubcategories(subCategoriesDefinitions);
-		}
-		return TitanOperationStatus.OK;
-	}
+                log.trace("Found sub-category {} for category {}, category type {}", subCategoryDataDefinition.getName(), categoryName, parentNodeType);
+                TitanOperationStatus setGroupings = setGroupings(childNodeType, subCategoryDefinition);
+                if (setGroupings != TitanOperationStatus.OK) {
+                    log.debug("Failed to set groupings for sub-category {}, sub-category type {}, error {}", subCategoryDataDefinition.getName(), childNodeType, setGroupings);
+                    return TitanOperationStatus.GENERAL_ERROR;
+                }
+                subCategoriesDefinitions.add(subCategoryDefinition);
+            }
+            parentCategory.setSubcategories(subCategoriesDefinitions);
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private TitanOperationStatus setGroupings(NodeTypeEnum parentNodeType, SubCategoryDefinition parentSubCategory) {
-		NodeTypeEnum childNodeType = getChildNodeType(parentNodeType);
-		if (childNodeType != null) {
-			String subCategoryName = parentSubCategory.getName();
-			log.trace("Getting groupings for subcategory {}, subcategory type {}", subCategoryName, parentNodeType);
-			Either<List<ImmutablePair<GroupingData, GraphEdge>>, TitanOperationStatus> parentNode = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentSubCategory.getUniqueId(), GraphEdgeLabels.GROUPING,
-					childNodeType, GroupingData.class);
-			if (parentNode.isRight()) {
-				TitanOperationStatus titanOperationStatus = parentNode.right().value();
-				if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
-					log.trace("Didn't find groupings for subcategory {}, subcategory type {}", subCategoryName, parentNodeType);
-					titanOperationStatus = TitanOperationStatus.OK;
-				}
-				return titanOperationStatus;
-			}
-			List<ImmutablePair<GroupingData, GraphEdge>> groupingData = parentNode.left().value();
-			List<GroupingDefinition> groupingDefinitions = new ArrayList<>();
-			for (ImmutablePair<GroupingData, GraphEdge> groupPair : groupingData) {
-				GroupingDataDefinition groupingDataDefinition = groupPair.getLeft().getGroupingDataDefinition();
-				log.trace("Found grouping {} for sub-category {}, sub-category type {}", groupingDataDefinition.getName(), subCategoryName, parentNodeType);
-				groupingDefinitions.add(new GroupingDefinition(groupingDataDefinition));
-			}
-			parentSubCategory.setGroupings(groupingDefinitions);
-		}
-		return TitanOperationStatus.OK;
-	}
+    private TitanOperationStatus setGroupings(NodeTypeEnum parentNodeType, SubCategoryDefinition parentSubCategory) {
+        NodeTypeEnum childNodeType = getChildNodeType(parentNodeType);
+        if (childNodeType != null) {
+            String subCategoryName = parentSubCategory.getName();
+            log.trace("Getting groupings for subcategory {}, subcategory type {}", subCategoryName, parentNodeType);
+            Either<List<ImmutablePair<GroupingData, GraphEdge>>, TitanOperationStatus> parentNode = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentSubCategory.getUniqueId(), GraphEdgeLabels.GROUPING,
+                    childNodeType, GroupingData.class);
+            if (parentNode.isRight()) {
+                TitanOperationStatus titanOperationStatus = parentNode.right().value();
+                if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
+                    log.trace("Didn't find groupings for subcategory {}, subcategory type {}", subCategoryName, parentNodeType);
+                    titanOperationStatus = TitanOperationStatus.OK;
+                }
+                return titanOperationStatus;
+            }
+            List<ImmutablePair<GroupingData, GraphEdge>> groupingData = parentNode.left().value();
+            List<GroupingDefinition> groupingDefinitions = new ArrayList<>();
+            for (ImmutablePair<GroupingData, GraphEdge> groupPair : groupingData) {
+                GroupingDataDefinition groupingDataDefinition = groupPair.getLeft().getGroupingDataDefinition();
+                log.trace("Found grouping {} for sub-category {}, sub-category type {}", groupingDataDefinition.getName(), subCategoryName, parentNodeType);
+                groupingDefinitions.add(new GroupingDefinition(groupingDataDefinition));
+            }
+            parentSubCategory.setGroupings(groupingDefinitions);
+        }
+        return TitanOperationStatus.OK;
+    }
 
-	private static NodeTypeEnum getChildNodeType(NodeTypeEnum parentTypeEnum) {
-		NodeTypeEnum res = null;
-		switch (parentTypeEnum) {
-		case ResourceNewCategory:
-			res = NodeTypeEnum.ResourceSubcategory;
-			break;
-		case ProductCategory:
-			res = NodeTypeEnum.ProductSubcategory;
-			break;
-		case ProductSubcategory:
-			res = NodeTypeEnum.ProductGrouping;
-			break;
-		default:
-			break;
-		}
-		return res;
-	}
+    private static NodeTypeEnum getChildNodeType(NodeTypeEnum parentTypeEnum) {
+        NodeTypeEnum res = null;
+        switch (parentTypeEnum) {
+        case ResourceNewCategory:
+            res = NodeTypeEnum.ResourceSubcategory;
+            break;
+        case ProductCategory:
+            res = NodeTypeEnum.ProductSubcategory;
+            break;
+        case ProductSubcategory:
+            res = NodeTypeEnum.ProductGrouping;
+            break;
+        default:
+            break;
+        }
+        return res;
+    }
 
-	@Override
-	public Either<CategoryDefinition, ActionStatus> getCategory(NodeTypeEnum nodeType, String categoryId) {
-		try {
-			if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory && nodeType != NodeTypeEnum.ProductCategory) {
-				log.debug("Unknown category type {}", nodeType.name());
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
+    @Override
+    public Either<CategoryDefinition, ActionStatus> getCategory(NodeTypeEnum nodeType, String categoryId) {
+        try {
+            if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory && nodeType != NodeTypeEnum.ProductCategory) {
+                log.debug(UNKNOWN_CATEGORY_TYPE, nodeType.name());
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
 
-			Either<CategoryData, TitanOperationStatus> categoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class);
-			if (categoryDataEither.isRight()) {
-				TitanOperationStatus titanOperationStatus = categoryDataEither.right().value();
-				log.debug("Problem while get category by id {}. reason {}", categoryId, titanOperationStatus);
-				if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
-					return Either.right(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND);
-				}
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
-			CategoryDataDefinition categoryDataDefinition = categoryDataEither.left().value().getCategoryDataDefinition();
-			return Either.left(new CategoryDefinition(categoryDataDefinition));
-		} finally {
-			titanGenericDao.commit();
-		}
-	}
+            Either<CategoryData, TitanOperationStatus> categoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class);
+            if (categoryDataEither.isRight()) {
+                TitanOperationStatus titanOperationStatus = categoryDataEither.right().value();
+                log.debug("Problem while get category by id {}. reason {}", categoryId, titanOperationStatus);
+                if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
+                    return Either.right(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND);
+                }
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
+            CategoryDataDefinition categoryDataDefinition = categoryDataEither.left().value().getCategoryDataDefinition();
+            return Either.left(new CategoryDefinition(categoryDataDefinition));
+        } finally {
+            titanGenericDao.commit();
+        }
+    }
 
-	@Override
-	public Either<SubCategoryDefinition, ActionStatus> getSubCategory(NodeTypeEnum nodeType, String subCategoryId) {
-		try {
-			if (nodeType != NodeTypeEnum.ResourceSubcategory && nodeType != NodeTypeEnum.ProductSubcategory) {
-				log.debug("Unknown sub-category type {}", nodeType.name());
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
+    @Override
+    public Either<SubCategoryDefinition, ActionStatus> getSubCategory(NodeTypeEnum nodeType, String subCategoryId) {
+        try {
+            if (nodeType != NodeTypeEnum.ResourceSubcategory && nodeType != NodeTypeEnum.ProductSubcategory) {
+                log.debug("Unknown sub-category type {}", nodeType.name());
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
 
-			Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
-			if (subCategoryDataEither.isRight()) {
-				TitanOperationStatus titanOperationStatus = subCategoryDataEither.right().value();
-				log.debug("Problem while get sub-category by id {}. reason {}", subCategoryId, titanOperationStatus);
-				if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
-					return Either.right(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND);
-				}
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
-			SubCategoryDataDefinition subCategoryDataDefinition = subCategoryDataEither.left().value().getSubCategoryDataDefinition();
-			return Either.left(new SubCategoryDefinition(subCategoryDataDefinition));
-		} finally {
-			titanGenericDao.commit();
-		}
-	}
+            Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
+            if (subCategoryDataEither.isRight()) {
+                TitanOperationStatus titanOperationStatus = subCategoryDataEither.right().value();
+                log.debug("Problem while get sub-category by id {}. reason {}", subCategoryId, titanOperationStatus);
+                if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
+                    return Either.right(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND);
+                }
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
+            SubCategoryDataDefinition subCategoryDataDefinition = subCategoryDataEither.left().value().getSubCategoryDataDefinition();
+            return Either.left(new SubCategoryDefinition(subCategoryDataDefinition));
+        } finally {
+            titanGenericDao.commit();
+        }
+    }
 
-	@Override
-	public Either<CategoryDefinition, ActionStatus> deleteCategory(NodeTypeEnum nodeType, String categoryId) {
-		Either<CategoryDefinition, ActionStatus> result = null;
-		try {
-			if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory && nodeType != NodeTypeEnum.ProductCategory) {
-				log.debug("Unknown category type {}", nodeType.name());
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
-			Either<CategoryData, TitanOperationStatus> categoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class);
-			if (categoryDataEither.isRight()) {
-				log.debug("Failed to retrieve  category for id {} ", categoryId);
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
+    @Override
+    public Either<CategoryDefinition, ActionStatus> deleteCategory(NodeTypeEnum nodeType, String categoryId) {
+        Either<CategoryDefinition, ActionStatus> result = null;
+        try {
+            if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory && nodeType != NodeTypeEnum.ProductCategory) {
+                log.debug(UNKNOWN_CATEGORY_TYPE, nodeType.name());
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
+            Either<CategoryData, TitanOperationStatus> categoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class);
+            if (categoryDataEither.isRight()) {
+                log.debug("Failed to retrieve  category for id {} ", categoryId);
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
 
-			Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
-			if (graph.isRight()) {
-				log.debug("Couldn't fetch titan graph");
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
+            Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
+            if (graph.isRight()) {
+                log.debug(COULDN_T_FETCH_TITAN_GRAPH);
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
 
-			TitanGraph tGraph = graph.left().value();
+            TitanGraph tGraph = graph.left().value();
 
-			Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId).vertices();
-			Iterator<TitanVertex> iterator = verticesArtifact.iterator();
-			if (!iterator.hasNext()) {
-				log.debug("No category node for id = {}", categoryId);
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
-			Vertex artifactV = iterator.next();
-			artifactV.remove();
-			CategoryDefinition deleted = new CategoryDefinition(categoryDataEither.left().value().getCategoryDataDefinition());
-			result = Either.left(deleted);
-			return result;
-		} finally {
-			if (result != null && result.isLeft()) {
-				titanGenericDao.commit();
-			} else {
-				titanGenericDao.rollback();
-			}
-		}
-	}
+            Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId).vertices();
+            Iterator<TitanVertex> iterator = verticesArtifact.iterator();
+            if (!iterator.hasNext()) {
+                log.debug("No category node for id = {}", categoryId);
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
+            Vertex artifactV = iterator.next();
+            artifactV.remove();
+            CategoryDefinition deleted = new CategoryDefinition(categoryDataEither.left().value().getCategoryDataDefinition());
+            result = Either.left(deleted);
+            return result;
+        } finally {
+            if (result != null && result.isLeft()) {
+                titanGenericDao.commit();
+            } else {
+                titanGenericDao.rollback();
+            }
+        }
+    }
 
-	@Override
-	public Either<SubCategoryDefinition, ActionStatus> deleteSubCategory(NodeTypeEnum nodeType, String subCategoryId) {
-		Either<SubCategoryDefinition, ActionStatus> result = null;
-		try {
-			if (nodeType != NodeTypeEnum.ResourceSubcategory && nodeType != NodeTypeEnum.ProductSubcategory) {
-				log.debug("Unknown sub-category type {}", nodeType.name());
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
-			Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
-			if (subCategoryDataEither.isRight()) {
-				log.debug("Failed to retrieve  sub-category for id {}", subCategoryId);
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
+    @Override
+    public Either<SubCategoryDefinition, ActionStatus> deleteSubCategory(NodeTypeEnum nodeType, String subCategoryId) {
+        Either<SubCategoryDefinition, ActionStatus> result = null;
+        try {
+            if (nodeType != NodeTypeEnum.ResourceSubcategory && nodeType != NodeTypeEnum.ProductSubcategory) {
+                log.debug("Unknown sub-category type {}", nodeType.name());
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
+            Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
+            if (subCategoryDataEither.isRight()) {
+                log.debug("Failed to retrieve  sub-category for id {}", subCategoryId);
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
 
-			Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
-			if (graph.isRight()) {
-				log.debug("Couldn't fetch titan graph");
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
+            Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
+            if (graph.isRight()) {
+                log.debug(COULDN_T_FETCH_TITAN_GRAPH);
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
 
-			TitanGraph tGraph = graph.left().value();
+            TitanGraph tGraph = graph.left().value();
 
-			Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId).vertices();
-			Iterator<TitanVertex> iterator = verticesArtifact.iterator();
-			if (!iterator.hasNext()) {
-				log.debug("No sub-category node for id {}", subCategoryId);
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
-			Vertex artifactV = iterator.next();
-			artifactV.remove();
-			;
-			SubCategoryDefinition deleted = new SubCategoryDefinition(subCategoryDataEither.left().value().getSubCategoryDataDefinition());
-			result = Either.left(deleted);
-			return result;
-		} finally {
-			if (result != null && result.isLeft()) {
-				titanGenericDao.commit();
-			} else {
-				titanGenericDao.rollback();
-			}
-		}
+            Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId).vertices();
+            Iterator<TitanVertex> iterator = verticesArtifact.iterator();
+            if (!iterator.hasNext()) {
+                log.debug("No sub-category node for id {}", subCategoryId);
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
+            Vertex artifactV = iterator.next();
+            artifactV.remove();
+            ;
+            SubCategoryDefinition deleted = new SubCategoryDefinition(subCategoryDataEither.left().value().getSubCategoryDataDefinition());
+            result = Either.left(deleted);
+            return result;
+        } finally {
+            if (result != null && result.isLeft()) {
+                titanGenericDao.commit();
+            } else {
+                titanGenericDao.rollback();
+            }
+        }
 
-	}
+    }
 
-	@Override
-	public Either<GroupingDefinition, ActionStatus> deleteGrouping(NodeTypeEnum nodeType, String groupingId) {
-		Either<GroupingDefinition, ActionStatus> result = null;
-		try {
-			if (nodeType != NodeTypeEnum.ProductGrouping) {
-				log.debug("Unknown grouping type {}", nodeType.name());
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
-			Either<GroupingData, TitanOperationStatus> groupingDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId, GroupingData.class);
-			if (groupingDataEither.isRight()) {
-				log.debug("Failed to retrieve  grouping for id {}", groupingId);
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
+    @Override
+    public Either<GroupingDefinition, ActionStatus> deleteGrouping(NodeTypeEnum nodeType, String groupingId) {
+        Either<GroupingDefinition, ActionStatus> result = null;
+        try {
+            if (nodeType != NodeTypeEnum.ProductGrouping) {
+                log.debug("Unknown grouping type {}", nodeType.name());
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
+            Either<GroupingData, TitanOperationStatus> groupingDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId, GroupingData.class);
+            if (groupingDataEither.isRight()) {
+                log.debug("Failed to retrieve  grouping for id {}", groupingId);
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
 
-			Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
-			if (graph.isRight()) {
-				log.debug("Couldn't fetch titan graph");
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
+            Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
+            if (graph.isRight()) {
+                log.debug(COULDN_T_FETCH_TITAN_GRAPH);
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
 
-			TitanGraph tGraph = graph.left().value();
+            TitanGraph tGraph = graph.left().value();
 
-			Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId).vertices();
-			Iterator<TitanVertex> iterator = verticesArtifact.iterator();
-			if (!iterator.hasNext()) {
-				log.debug("No grouping node for id {}", groupingId);
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-				return result;
-			}
-			Vertex artifactV = iterator.next();
-			artifactV.remove();
-			;
-			GroupingDefinition deleted = new GroupingDefinition(groupingDataEither.left().value().getGroupingDataDefinition());
-			result = Either.left(deleted);
-			return result;
-		} finally {
-			if (result != null && result.isLeft()) {
-				titanGenericDao.commit();
-			} else {
-				titanGenericDao.rollback();
-			}
-		}
-	}
+            Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId).vertices();
+            Iterator<TitanVertex> iterator = verticesArtifact.iterator();
+            if (!iterator.hasNext()) {
+                log.debug("No grouping node for id {}", groupingId);
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+                return result;
+            }
+            Vertex artifactV = iterator.next();
+            artifactV.remove();
+            ;
+            GroupingDefinition deleted = new GroupingDefinition(groupingDataEither.left().value().getGroupingDataDefinition());
+            result = Either.left(deleted);
+            return result;
+        } finally {
+            if (result != null && result.isLeft()) {
+                titanGenericDao.commit();
+            } else {
+                titanGenericDao.rollback();
+            }
+        }
+    }
 
-	@Override
-	public Either<Boolean, ActionStatus> isCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName) {
+    @Override
+    public Either<Boolean, ActionStatus> isCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName) {
 
-		Map<String, Object> properties = new HashMap<>();
-		properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName);
-		try {
-			Either<List<CategoryData>, TitanOperationStatus> categoryEither = titanGenericDao.getByCriteria(nodeType, properties, CategoryData.class);
-			if (categoryEither.isRight() && categoryEither.right().value() != TitanOperationStatus.NOT_FOUND) {
-				log.debug("Failed to get categories, nodeType {}, normalizedName {}, error {}", nodeType, normalizedName, categoryEither.right().value());
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
-			List<CategoryData> categoryList = (categoryEither.isLeft() ? categoryEither.left().value() : null);
-			if (categoryList != null && categoryList.size() > 0) {
-				log.debug("Found category for nodeType {} with normalizedName {}", nodeType, normalizedName);
-				if (categoryList.size() > 1) {
-					log.debug("Found more than 1 unique categories for nodeType {} with normalizedName", nodeType, normalizedName);
-					return Either.right(ActionStatus.GENERAL_ERROR);
-				}
-				return Either.left(false);
-			} else {
-				log.debug("Category for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, normalizedName);
-				return Either.left(true);
-			}
-		} finally {
-			titanGenericDao.commit();
-		}
-	}
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName);
+        try {
+            Either<List<CategoryData>, TitanOperationStatus> categoryEither = titanGenericDao.getByCriteria(nodeType, properties, CategoryData.class);
+            if (categoryEither.isRight() && categoryEither.right().value() != TitanOperationStatus.NOT_FOUND) {
+                log.debug("Failed to get categories, nodeType {}, normalizedName {}, error {}", nodeType, normalizedName, categoryEither.right().value());
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
+            List<CategoryData> categoryList = (categoryEither.isLeft() ? categoryEither.left().value() : null);
+            if (categoryList != null && categoryList.size() > 0) {
+                log.debug("Found category for nodeType {} with normalizedName {}", nodeType, normalizedName);
+                if (categoryList.size() > 1) {
+                    log.debug("Found more than 1 unique categories for nodeType {} with normalizedName", nodeType, normalizedName);
+                    return Either.right(ActionStatus.GENERAL_ERROR);
+                }
+                return Either.left(false);
+            } else {
+                log.debug("Category for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, normalizedName);
+                return Either.left(true);
+            }
+        } finally {
+            titanGenericDao.commit();
+        }
+    }
 
-	@Override
-	public Either<Boolean, ActionStatus> isSubCategoryUniqueForCategory(NodeTypeEnum nodeType, String subCategoryNormName, String parentCategoryId) {
+    @Override
+    public Either<Boolean, ActionStatus> isSubCategoryUniqueForCategory(NodeTypeEnum nodeType, String subCategoryNormName, String parentCategoryId) {
 
-		String subCategoryId = UniqueIdBuilder.buildSubCategoryUid(parentCategoryId, subCategoryNormName);
-		try {
-			Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
-			if (subCategoryDataEither.isRight() && subCategoryDataEither.right().value() != TitanOperationStatus.NOT_FOUND) {
-				log.debug("Failed to get sub-category with id {}, error {}", subCategoryId, subCategoryDataEither.right().value());
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
-			SubCategoryData subCategoryData = (subCategoryDataEither.isLeft() ? subCategoryDataEither.left().value() : null);
-			if (subCategoryData != null) {
-				log.debug("Found sub-category with id {}", subCategoryId);
-				return Either.left(false);
-			} else {
-				log.debug("Sub-category for id {} doesn't exist in graph", subCategoryId);
-				return Either.left(true);
-			}
-		} finally {
-			titanGenericDao.commit();
-		}
-	}
+        String subCategoryId = UniqueIdBuilder.buildSubCategoryUid(parentCategoryId, subCategoryNormName);
+        try {
+            Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class);
+            if (subCategoryDataEither.isRight() && subCategoryDataEither.right().value() != TitanOperationStatus.NOT_FOUND) {
+                log.debug("Failed to get sub-category with id {}, error {}", subCategoryId, subCategoryDataEither.right().value());
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
+            SubCategoryData subCategoryData = (subCategoryDataEither.isLeft() ? subCategoryDataEither.left().value() : null);
+            if (subCategoryData != null) {
+                log.debug("Found sub-category with id {}", subCategoryId);
+                return Either.left(false);
+            } else {
+                log.debug("Sub-category for id {} doesn't exist in graph", subCategoryId);
+                return Either.left(true);
+            }
+        } finally {
+            titanGenericDao.commit();
+        }
+    }
 
-	@Override
-	public Either<Boolean, ActionStatus> isGroupingUniqueForSubCategory(NodeTypeEnum nodeType, String groupingNormName, String parentSubCategoryId) {
+    @Override
+    public Either<Boolean, ActionStatus> isGroupingUniqueForSubCategory(NodeTypeEnum nodeType, String groupingNormName, String parentSubCategoryId) {
 
-		String groupingId = UniqueIdBuilder.buildGroupingUid(parentSubCategoryId, groupingNormName);
-		try {
-			Either<GroupingData, TitanOperationStatus> groupingDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId, GroupingData.class);
-			if (groupingDataEither.isRight() && groupingDataEither.right().value() != TitanOperationStatus.NOT_FOUND) {
-				log.debug("Failed to get grouping with id {}, error {}", groupingId, groupingDataEither.right().value());
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
-			GroupingData groupingData = (groupingDataEither.isLeft() ? groupingDataEither.left().value() : null);
-			if (groupingData != null) {
-				log.debug("Found grouping with id {}", groupingId);
-				return Either.left(false);
-			} else {
-				log.debug("Grouping for id {} doesn't exist in graph", groupingId);
-				return Either.left(true);
-			}
-		} finally {
-			titanGenericDao.commit();
-		}
-	}
+        String groupingId = UniqueIdBuilder.buildGroupingUid(parentSubCategoryId, groupingNormName);
+        try {
+            Either<GroupingData, TitanOperationStatus> groupingDataEither = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId, GroupingData.class);
+            if (groupingDataEither.isRight() && groupingDataEither.right().value() != TitanOperationStatus.NOT_FOUND) {
+                log.debug("Failed to get grouping with id {}, error {}", groupingId, groupingDataEither.right().value());
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
+            GroupingData groupingData = (groupingDataEither.isLeft() ? groupingDataEither.left().value() : null);
+            if (groupingData != null) {
+                log.debug("Found grouping with id {}", groupingId);
+                return Either.left(false);
+            } else {
+                log.debug("Grouping for id {} doesn't exist in graph", groupingId);
+                return Either.left(true);
+            }
+        } finally {
+            titanGenericDao.commit();
+        }
+    }
 
-	@Override
-	public Either<SubCategoryDefinition, ActionStatus> getSubCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName) {
-		Map<String, Object> properties = new HashMap<>();
-		properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName);
-		try {
-			Either<List<SubCategoryData>, TitanOperationStatus> subCategoryEither = titanGenericDao.getByCriteria(nodeType, properties, SubCategoryData.class);
-			if (subCategoryEither.isRight() && subCategoryEither.right().value() != TitanOperationStatus.NOT_FOUND) {
-				log.debug("Failed to get sub-categories, nodeType {}, normalizedName {}, error {}", nodeType, normalizedName, subCategoryEither.right().value());
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
-			List<SubCategoryData> subCategoryList = (subCategoryEither.isLeft() ? subCategoryEither.left().value() : null);
-			if (subCategoryList != null && subCategoryList.size() > 0) {
-				log.debug("Found sub-category for nodeType {} with normalizedName {}", nodeType, normalizedName);
-				SubCategoryData subCategoryData = subCategoryList.get(0);
-				SubCategoryDefinition subCategoryDefinition = new SubCategoryDefinition(subCategoryData.getSubCategoryDataDefinition());
-				return Either.left(subCategoryDefinition);
-			} else {
-				log.debug("Sub-category for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, normalizedName);
-				return Either.left(null);
-			}
-		} finally {
-			titanGenericDao.commit();
-		}
-	}
+    @Override
+    public Either<SubCategoryDefinition, ActionStatus> getSubCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName) {
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName);
+        try {
+            Either<List<SubCategoryData>, TitanOperationStatus> subCategoryEither = titanGenericDao.getByCriteria(nodeType, properties, SubCategoryData.class);
+            if (subCategoryEither.isRight() && subCategoryEither.right().value() != TitanOperationStatus.NOT_FOUND) {
+                log.debug("Failed to get sub-categories, nodeType {}, normalizedName {}, error {}", nodeType, normalizedName, subCategoryEither.right().value());
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
+            List<SubCategoryData> subCategoryList = (subCategoryEither.isLeft() ? subCategoryEither.left().value() : null);
+            if (subCategoryList != null && subCategoryList.size() > 0) {
+                log.debug("Found sub-category for nodeType {} with normalizedName {}", nodeType, normalizedName);
+                SubCategoryData subCategoryData = subCategoryList.get(0);
+                SubCategoryDefinition subCategoryDefinition = new SubCategoryDefinition(subCategoryData.getSubCategoryDataDefinition());
+                return Either.left(subCategoryDefinition);
+            } else {
+                log.debug("Sub-category for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, normalizedName);
+                return Either.left(null);
+            }
+        } finally {
+            titanGenericDao.commit();
+        }
+    }
 
-	@Override
-	public Either<GroupingDefinition, ActionStatus> getGroupingUniqueForType(NodeTypeEnum nodeType, String groupingNormalizedName) {
-		Map<String, Object> properties = new HashMap<>();
-		properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), groupingNormalizedName);
-		try {
-			Either<List<GroupingData>, TitanOperationStatus> groupingEither = titanGenericDao.getByCriteria(nodeType, properties, GroupingData.class);
-			if (groupingEither.isRight() && groupingEither.right().value() != TitanOperationStatus.NOT_FOUND) {
-				log.debug("Failed to get grouping, nodeType {}, normalizedName {}, error {}", nodeType, groupingNormalizedName, groupingEither.right().value());
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
-			List<GroupingData> groupingList = (groupingEither.isLeft() ? groupingEither.left().value() : null);
-			if (groupingList != null && groupingList.size() > 0) {
-				log.debug("Found grouping for nodeType {} with normalizedName {}", nodeType, groupingNormalizedName);
-				GroupingData groupingData = groupingList.get(0);
-				GroupingDefinition groupingDefinition = new GroupingDefinition(groupingData.getGroupingDataDefinition());
-				return Either.left(groupingDefinition);
-			} else {
-				log.debug("Grouping for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, groupingNormalizedName);
-				return Either.left(null);
-			}
-		} finally {
-			titanGenericDao.commit();
-		}
-	}
+    @Override
+    public Either<GroupingDefinition, ActionStatus> getGroupingUniqueForType(NodeTypeEnum nodeType, String groupingNormalizedName) {
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), groupingNormalizedName);
+        try {
+            Either<List<GroupingData>, TitanOperationStatus> groupingEither = titanGenericDao.getByCriteria(nodeType, properties, GroupingData.class);
+            if (groupingEither.isRight() && groupingEither.right().value() != TitanOperationStatus.NOT_FOUND) {
+                log.debug("Failed to get grouping, nodeType {}, normalizedName {}, error {}", nodeType, groupingNormalizedName, groupingEither.right().value());
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
+            List<GroupingData> groupingList = (groupingEither.isLeft() ? groupingEither.left().value() : null);
+            if (groupingList != null && groupingList.size() > 0) {
+                log.debug("Found grouping for nodeType {} with normalizedName {}", nodeType, groupingNormalizedName);
+                GroupingData groupingData = groupingList.get(0);
+                GroupingDefinition groupingDefinition = new GroupingDefinition(groupingData.getGroupingDataDefinition());
+                return Either.left(groupingDefinition);
+            } else {
+                log.debug("Grouping for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, groupingNormalizedName);
+                return Either.left(null);
+            }
+        } finally {
+            titanGenericDao.commit();
+        }
+    }
 
-	/*
-	 *
-	 */
+    /*
+     *
+     */
 
-	@Override
-	public Either<List<Tag>, ActionStatus> getAllTags() {
-		try {
-			Either<List<TagData>, TitanOperationStatus> either = titanGenericDao.getAll(NodeTypeEnum.Tag, TagData.class);
-			if (either.isRight()) {
-				log.debug("Problem while get all tags. reason - {}", either.right().value());
-				return Either.right(ActionStatus.GENERAL_ERROR);
-			}
-			List<TagData> tagDataList = either.left().value();
-			List<Tag> tagList = convertToListOfTag(tagDataList);
-			return Either.left(tagList);
-		} finally {
-			titanGenericDao.commit();
-		}
-	}
+    @Override
+    public Either<List<Tag>, ActionStatus> getAllTags() {
+        try {
+            Either<List<TagData>, TitanOperationStatus> either = titanGenericDao.getAll(NodeTypeEnum.Tag, TagData.class);
+            if (either.isRight()) {
+                log.debug("Problem while get all tags. reason - {}", either.right().value());
+                return Either.right(ActionStatus.GENERAL_ERROR);
+            }
+            List<TagData> tagDataList = either.left().value();
+            List<Tag> tagList = convertToListOfTag(tagDataList);
+            return Either.left(tagList);
+        } finally {
+            titanGenericDao.commit();
+        }
+    }
 
-	@Override
-	public <T extends GraphNode> Either<org.openecomp.sdc.be.resources.data.CategoryData, StorageOperationStatus> getCategoryData(String name, NodeTypeEnum type, Class<T> clazz) {
-		if (name != null) {
-			String categoryUid = null;
-			if (type == NodeTypeEnum.ResourceCategory) {
-				String[] categoryFields = name.split("/");
-				if (categoryFields.length != 2) {
-					return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
-				}
-				categoryUid = UniqueIdBuilder.buildResourceCategoryUid(categoryFields[0], categoryFields[1], type);
-			} else {
-				categoryUid = UniqueIdBuilder.buildServiceCategoryUid(name, type);
-			}
-			Either<T, TitanOperationStatus> either = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(type), categoryUid, clazz);
+    @Override
+    public <T extends GraphNode> Either<org.openecomp.sdc.be.resources.data.CategoryData, StorageOperationStatus> getCategoryData(String name, NodeTypeEnum type, Class<T> clazz) {
+        if (name != null) {
+            String categoryUid = null;
+            if (type == NodeTypeEnum.ResourceCategory) {
+                String[] categoryFields = name.split("/");
+                if (categoryFields.length != 2) {
+                    return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
+                }
+                categoryUid = UniqueIdBuilder.buildResourceCategoryUid(categoryFields[0], categoryFields[1], type);
+            } else {
+                categoryUid = UniqueIdBuilder.buildServiceCategoryUid(name, type);
+            }
+            Either<T, TitanOperationStatus> either = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(type), categoryUid, clazz);
 
-			if (either.isRight()) {
-				TitanOperationStatus titanOperationStatus = either.right().value();
-				log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name());
-				if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
-					return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
-				} else {
-					return Either.right(StorageOperationStatus.GENERAL_ERROR);
-				}
-			}
-			return Either.left((org.openecomp.sdc.be.resources.data.CategoryData) either.left().value());
-		} else {
-			return Either.right(StorageOperationStatus.GENERAL_ERROR);
-		}
-	}
+            if (either.isRight()) {
+                TitanOperationStatus titanOperationStatus = either.right().value();
+                log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name());
+                if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
+                    return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
+                } else {
+                    return Either.right(StorageOperationStatus.GENERAL_ERROR);
+                }
+            }
+            return Either.left((org.openecomp.sdc.be.resources.data.CategoryData) either.left().value());
+        } else {
+            return Either.right(StorageOperationStatus.GENERAL_ERROR);
+        }
+    }
 
-	private List<Tag> convertToListOfTag(List<TagData> tagDataList) {
-		List<Tag> tagList = new ArrayList<Tag>();
-		for (TagData elem : tagDataList) {
-			Tag tag = new Tag();
-			tag.setName(elem.getName());
-			tagList.add(tag);
-		}
-		return tagList;
-	}
+    private List<Tag> convertToListOfTag(List<TagData> tagDataList) {
+        List<Tag> tagList = new ArrayList<>();
+        for (TagData elem : tagDataList) {
+            Tag tag = new Tag();
+            tag.setName(elem.getName());
+            tagList.add(tag);
+        }
+        return tagList;
+    }
 
-	@Override
-	public Either<List<PropertyScope>, ActionStatus> getAllPropertyScopes() {
-		// Mock
-		List<PropertyScope> propertyScopes = new ArrayList<PropertyScope>();
-		PropertyScope propertyScope1 = new PropertyScope();
-		propertyScope1.setName("A&AI");
-		PropertyScope propertyScope2 = new PropertyScope();
-		propertyScope2.setName("Order");
-		PropertyScope propertyScope3 = new PropertyScope();
-		propertyScope3.setName("Runtime");
-		propertyScopes.add(propertyScope1);
-		propertyScopes.add(propertyScope2);
-		propertyScopes.add(propertyScope3);
-		return Either.left(propertyScopes);
-	}
+    @Override
+    public Either<List<PropertyScope>, ActionStatus> getAllPropertyScopes() {
+        // Mock
+        List<PropertyScope> propertyScopes = new ArrayList<>();
+        PropertyScope propertyScope1 = new PropertyScope();
+        propertyScope1.setName("A&AI");
+        PropertyScope propertyScope2 = new PropertyScope();
+        propertyScope2.setName("Order");
+        PropertyScope propertyScope3 = new PropertyScope();
+        propertyScope3.setName("Runtime");
+        propertyScopes.add(propertyScope1);
+        propertyScopes.add(propertyScope2);
+        propertyScopes.add(propertyScope3);
+        return Either.left(propertyScopes);
+    }
 
-	@Override
-	public Either<List<ArtifactType>, ActionStatus> getAllArtifactTypes() {
-		List<ArtifactType> artifactTypes = new ArrayList<ArtifactType>();
+    @Override
+    public Either<List<ArtifactType>, ActionStatus> getAllArtifactTypes() {
+        List<ArtifactType> artifactTypes = new ArrayList<>();
 
-		List<String> artifactTypesList = ConfigurationManager.getConfigurationManager().getConfiguration().getArtifactTypes();
-		for (String artifactType : artifactTypesList) {
-			ArtifactType artifactT = new ArtifactType();
-			artifactT.setName(artifactType);
-			artifactTypes.add(artifactT);
-		}
-		return Either.left(artifactTypes);
-	}
+        List<String> artifactTypesList = ConfigurationManager.getConfigurationManager().getConfiguration().getArtifactTypes();
+        for (String artifactType : artifactTypesList) {
+            ArtifactType artifactT = new ArtifactType();
+            artifactT.setName(artifactType);
+            artifactTypes.add(artifactT);
+        }
+        return Either.left(artifactTypes);
+    }
 
-	@Override
-	public Either<Map<String, Object>, ActionStatus> getAllDeploymentArtifactTypes() {
+    @Override
+    public Either<Map<String, Object>, ActionStatus> getAllDeploymentArtifactTypes() {
 
-		Map<String, Object> artifactTypes = new HashMap<String, Object>();
-		Map<String, ArtifactTypeConfig> artifactResourceTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceDeploymentArtifacts();
-		Map<String, ArtifactTypeConfig> artifactServiceTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceDeploymentArtifacts();
-		Map<String, ArtifactTypeConfig> artifactResourceInstanceTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts();
+        Map<String, Object> artifactTypes = new HashMap<>();
+        Map<String, ArtifactTypeConfig> artifactResourceTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceDeploymentArtifacts();
+        Map<String, ArtifactTypeConfig> artifactServiceTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceDeploymentArtifacts();
+        Map<String, ArtifactTypeConfig> artifactResourceInstanceTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts();
 
-		artifactTypes.put("resourceDeploymentArtifacts", artifactResourceTypes);
-		artifactTypes.put("serviceDeploymentArtifacts", artifactServiceTypes);
-		artifactTypes.put("resourceInstanceDeploymentArtifacts", artifactResourceInstanceTypes);
+        artifactTypes.put("resourceDeploymentArtifacts", artifactResourceTypes);
+        artifactTypes.put("serviceDeploymentArtifacts", artifactServiceTypes);
+        artifactTypes.put("resourceInstanceDeploymentArtifacts", artifactResourceInstanceTypes);
 
-		return Either.left(artifactTypes);
+        return Either.left(artifactTypes);
 
-	}
+    }
 
-	@Override
-	public Either<Integer, ActionStatus> getDefaultHeatTimeout() {
-		return Either.left(ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes());
-	}
+    @Override
+    public Either<Integer, ActionStatus> getDefaultHeatTimeout() {
+        return Either.left(ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes());
+    }
 
-	@Override
-	public Either<Map<String, String>, ActionStatus> getResourceTypesMap() {
-		ResourceTypeEnum[] enumConstants = ResourceTypeEnum.class.getEnumConstants();
-		Map<String, String> resourceTypes = new HashMap<String, String>();
-		if (enumConstants != null) {
-			for (int i = 0; i < enumConstants.length; ++i) {
-				resourceTypes.put(enumConstants[i].name(), enumConstants[i].getValue());
-			}
+    @Override
+    public Either<Map<String, String>, ActionStatus> getResourceTypesMap() {
+        ResourceTypeEnum[] enumConstants = ResourceTypeEnum.class.getEnumConstants();
+        Map<String, String> resourceTypes = new HashMap<>();
+        if (enumConstants != null) {
+            for (int i = 0; i < enumConstants.length; ++i) {
+                resourceTypes.put(enumConstants[i].name(), enumConstants[i].getValue());
+            }
 
-		}
-		return Either.left(resourceTypes);
-	}
+        }
+        return Either.left(resourceTypes);
+    }
 
-	@Override
-	public <T extends GraphNode> Either<CategoryData, StorageOperationStatus> getNewCategoryData(String name, NodeTypeEnum type, Class<T> clazz) {
-		if (name != null) {
-			String categoryUid = UniqueIdBuilder.buildServiceCategoryUid(name, type);
-			Map props = new HashMap<>();
-			props.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), ValidationUtils.normalizeCategoryName4Uniqueness(name));
-			Either<List<T>, TitanOperationStatus> either = titanGenericDao.getByCriteria(type, props, clazz);
+    @Override
+    public <T extends GraphNode> Either<CategoryData, StorageOperationStatus> getNewCategoryData(String name, NodeTypeEnum type, Class<T> clazz) {
+        if (name != null) {
+            String categoryUid = UniqueIdBuilder.buildServiceCategoryUid(name, type);
+            Map props = new HashMap<>();
+            props.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), ValidationUtils.normalizeCategoryName4Uniqueness(name));
+            Either<List<T>, TitanOperationStatus> either = titanGenericDao.getByCriteria(type, props, clazz);
 
-			if (either.isRight()) {
-				TitanOperationStatus titanOperationStatus = either.right().value();
-				log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name());
-				if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
-					return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
-				} else {
-					return Either.right(StorageOperationStatus.GENERAL_ERROR);
-				}
-			}
-			return Either.left((CategoryData) either.left().value().get(0));
-		} else {
-			return Either.right(StorageOperationStatus.GENERAL_ERROR);
-		}
-	}
+            if (either.isRight()) {
+                TitanOperationStatus titanOperationStatus = either.right().value();
+                log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name());
+                if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
+                    return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
+                } else {
+                    return Either.right(StorageOperationStatus.GENERAL_ERROR);
+                }
+            }
+            return Either.left((CategoryData) either.left().value().get(0));
+        } else {
+            return Either.right(StorageOperationStatus.GENERAL_ERROR);
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java
index e5a743a..b87da5a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java
@@ -25,74 +25,71 @@
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
 @Component("graph-lock-operation")
 public class GraphLockOperation implements IGraphLockOperation {
-	private static Logger log = LoggerFactory.getLogger(GraphLockOperation.class.getName());
+    private static final Logger log = Logger.getLogger(GraphLockOperation.class.getName());
 
-	@javax.annotation.Resource
-	private TitanGenericDao titanGenericDao;
+    @javax.annotation.Resource
+    private TitanGenericDao titanGenericDao;
 
-	public GraphLockOperation() {
-		super();
-	}
+    public GraphLockOperation() {
+        super();
+    }
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.openecomp.sdc.be.model.operations.impl.IGraphLockOperation# lockResource(java.lang.String, org.openecomp.sdc.be.model.operations.api.IResourceOperation)
-	 */
-	@Override
-	public StorageOperationStatus lockComponent(String componentId, NodeTypeEnum nodeType) {
-		log.info("lock resource with id {}", componentId);
-		TitanOperationStatus lockElementStatus = null;
-		try {
-			lockElementStatus = titanGenericDao.lockElement(componentId, nodeType);
-		} catch (Exception e) {
-			lockElementStatus = TitanOperationStatus.ALREADY_LOCKED;
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.openecomp.sdc.be.model.operations.impl.IGraphLockOperation# lockResource(java.lang.String, org.openecomp.sdc.be.model.operations.api.IResourceOperation)
+     */
+    @Override
+    public StorageOperationStatus lockComponent(String componentId, NodeTypeEnum nodeType) {
+        log.info("lock resource with id {}", componentId);
+        TitanOperationStatus lockElementStatus = null;
+        try {
+            lockElementStatus = titanGenericDao.lockElement(componentId, nodeType);
+        } catch (Exception e) {
+            lockElementStatus = TitanOperationStatus.ALREADY_LOCKED;
 
-		}
+        }
 
-		return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus);
+        return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus);
 
-	}
+    }
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.openecomp.sdc.be.model.operations.impl.IGraphLockOperation# unlockResource(java.lang.String, org.openecomp.sdc.be.model.operations.api.IResourceOperation)
-	 */
-	@Override
-	public StorageOperationStatus unlockComponent(String componentId, NodeTypeEnum nodeType) {
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.openecomp.sdc.be.model.operations.impl.IGraphLockOperation# unlockResource(java.lang.String, org.openecomp.sdc.be.model.operations.api.IResourceOperation)
+     */
+    @Override
+    public StorageOperationStatus unlockComponent(String componentId, NodeTypeEnum nodeType) {
+        TitanOperationStatus lockElementStatus = titanGenericDao.releaseElement(componentId, nodeType);
+        return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus);
+    }
 
-		TitanOperationStatus lockElementStatus = titanGenericDao.releaseElement(componentId, nodeType);
+    @Override
+    public StorageOperationStatus unlockComponentByName(String name, String componentId, NodeTypeEnum nodeType) {
+        TitanOperationStatus lockElementStatus = titanGenericDao.releaseElement(name, nodeType);
+        return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus);
+    }
 
-		return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus);
-	}
+    @Override
+    public StorageOperationStatus lockComponentByName(String name, NodeTypeEnum nodeType) {
+        log.info("lock resource with name {}", name);
+        TitanOperationStatus lockElementStatus = null;
+        try {
 
-	@Override
-	public StorageOperationStatus unlockComponentByName(String name, String componentId, NodeTypeEnum nodeType) {
-		TitanOperationStatus lockElementStatus = titanGenericDao.releaseElement(name, nodeType);
-		return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus);
-	}
+            lockElementStatus = titanGenericDao.lockElement(name, nodeType);
 
-	@Override
-	public StorageOperationStatus lockComponentByName(String name, NodeTypeEnum nodeType) {
-		log.info("lock resource with name {}", name);
-		TitanOperationStatus lockElementStatus = null;
-		try {
+        } catch (Exception e) {
+            lockElementStatus = TitanOperationStatus.ALREADY_LOCKED;
 
-			lockElementStatus = titanGenericDao.lockElement(name, nodeType);
+        }
 
-		} catch (Exception e) {
-			lockElementStatus = TitanOperationStatus.ALREADY_LOCKED;
+        return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus);
 
-		}
-
-		return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus);
-
-	}
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupInstanceOperation.java
index 0b13fe1..4c86af4 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupInstanceOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupInstanceOperation.java
@@ -20,19 +20,12 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
@@ -40,772 +33,719 @@
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
-import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.GroupInstance;
-import org.openecomp.sdc.be.model.GroupInstanceProperty;
-import org.openecomp.sdc.be.model.GroupProperty;
-import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
-import org.openecomp.sdc.be.resources.data.ArtifactData;
-import org.openecomp.sdc.be.resources.data.GroupInstanceData;
-import org.openecomp.sdc.be.resources.data.PropertyData;
-import org.openecomp.sdc.be.resources.data.PropertyValueData;
-import org.openecomp.sdc.be.resources.data.UniqueIdData;
+import org.openecomp.sdc.be.resources.data.*;
 import org.openecomp.sdc.common.datastructure.Wrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.util.*;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
 
 @org.springframework.stereotype.Component("group-instance-operation")
 public class GroupInstanceOperation extends AbstractOperation implements IGroupInstanceOperation {
 
-	private static Logger log = LoggerFactory.getLogger(GroupInstanceOperation.class.getName());
+    private static final String UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE = "UpdatePropertyValueOnComponentInstance";
+	private static final String FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS = "Failed to update property value on instance. Status is ";
+	private static final Logger log = Logger.getLogger(GroupInstanceOperation.class.getName());
 
-	@Autowired
-	TitanGenericDao titanGenericDao;
-	@Autowired
-	GroupOperation groupOperation;
+    @Autowired
+    GroupOperation groupOperation;
 
-	@Autowired
-	PropertyOperation propertyOperation;
+    @Autowired
+    PropertyOperation propertyOperation;
 
-	@javax.annotation.Resource
-	private ApplicationDataTypeCache dataTypeCache;
+    @javax.annotation.Resource
+    private ApplicationDataTypeCache dataTypeCache;
 
 
-	@Override
-	public Either<List<GroupInstance>, StorageOperationStatus> getAllGroupInstances(String parentId, NodeTypeEnum parentType) {
-		Either<List<GroupInstance>, StorageOperationStatus> result = null;
-		List<GroupInstance> groupInstanceRes = new ArrayList<>();
+    @Override
+    public Either<List<GroupInstance>, StorageOperationStatus> getAllGroupInstances(String parentId, NodeTypeEnum parentType) {
+        Either<List<GroupInstance>, StorageOperationStatus> result = null;
+        List<GroupInstance> groupInstanceRes = new ArrayList<>();
 
-		Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
-		if (graph.isRight()) {
-			log.debug("Failed to work with graph {}", graph.right().value());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value()));
-		}
-		TitanGraph tGraph = graph.left().value();
-		@SuppressWarnings("unchecked")
-		Iterable<TitanVertex> vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices();
-		if (vertices == null || vertices.iterator() == null || false == vertices.iterator().hasNext()) {
-			log.debug("No nodes for type {}  for id = {}", parentType, parentId);
-			result = Either.right(StorageOperationStatus.NOT_FOUND);
-			return result;
-		}
+        Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
+        if (graph.isRight()) {
+            log.debug("Failed to work with graph {}", graph.right().value());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value()));
+        }
+        TitanGraph tGraph = graph.left().value();
+        @SuppressWarnings("unchecked")
+        Iterable<TitanVertex> vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices();
+        if (vertices == null || vertices.iterator() == null || !vertices.iterator().hasNext()) {
+            log.debug("No nodes for type {}  for id = {}", parentType, parentId);
+            result = Either.right(StorageOperationStatus.NOT_FOUND);
+            return result;
+        }
 
-		Iterator<TitanVertex> iterator = vertices.iterator();
-		Vertex vertex = iterator.next();
+        Iterator<TitanVertex> iterator = vertices.iterator();
+        Vertex vertex = iterator.next();
 
-		Map<String, Object> edgeProperties = null;
+        Map<String, Object> edgeProperties = null;
 
-		Either<List<ImmutablePair<GroupInstanceData, GraphEdge>>, TitanOperationStatus> childrenByEdgeCriteria = titanGenericDao.getChildrenByEdgeCriteria(vertex, parentId, GraphEdgeLabels.GROUP_INST, NodeTypeEnum.GroupInstance,
-				GroupInstanceData.class, edgeProperties);
+        Either<List<ImmutablePair<GroupInstanceData, GraphEdge>>, TitanOperationStatus> childrenByEdgeCriteria = titanGenericDao.getChildrenByEdgeCriteria(vertex, parentId, GraphEdgeLabels.GROUP_INST, NodeTypeEnum.GroupInstance,
+                GroupInstanceData.class, edgeProperties);
 
-		if (childrenByEdgeCriteria.isRight()) {
-			TitanOperationStatus status = childrenByEdgeCriteria.right().value();
-			log.debug("Failed to find group instance {} on graph", childrenByEdgeCriteria.right().value());
+        if (childrenByEdgeCriteria.isRight()) {
+            TitanOperationStatus status = childrenByEdgeCriteria.right().value();
+            log.debug("Failed to find group instance {} on graph", childrenByEdgeCriteria.right().value());
 
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				result = Either.left(groupInstanceRes);
-				return result;
-			}
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                return Either.left(groupInstanceRes);
+            }
+            
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
 
-		}
+        List<ImmutablePair<GroupInstanceData, GraphEdge>> list = childrenByEdgeCriteria.left().value();
 
-		List<ImmutablePair<GroupInstanceData, GraphEdge>> list = childrenByEdgeCriteria.left().value();
+        for (ImmutablePair<GroupInstanceData, GraphEdge> pair : list) {
+            GroupInstanceData groupInstData = pair.getLeft();
+            GroupInstance groupInstance = new GroupInstance(groupInstData.getGroupDataDefinition());
+            String instOriginGroupId = groupInstance.getGroupUid();
+            Either<GroupDefinition, StorageOperationStatus> groupRes = groupOperation.getGroupFromGraph(instOriginGroupId, false, true, false);
 
-		for (ImmutablePair<GroupInstanceData, GraphEdge> pair : list) {
-			GroupInstanceData groupInstData = pair.getLeft();
-			GroupInstance groupInstance = new GroupInstance(groupInstData.getGroupDataDefinition());
-			String instOriginGroupId = groupInstance.getGroupUid();
-			Either<GroupDefinition, TitanOperationStatus> groupRes = groupOperation.getGroupFromGraph(instOriginGroupId, false, true, false);
+            if (groupRes.isRight()) {
+                return Either.right(groupRes.right().value());
+            }
+            
+            GroupDefinition groupDefinition = groupRes.left().value();
+            Either<Map<String, PropertyValueData>, TitanOperationStatus> groupInstancePropertyValuesRes = getAllGroupInstancePropertyValuesData(groupInstData);
+            if(groupInstancePropertyValuesRes.isRight()){
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(groupInstancePropertyValuesRes.right().value()));
+            }
+            buildGroupInstanceFromGroup(groupInstance, groupDefinition, groupInstancePropertyValuesRes.left().value());
+            Either<List<ImmutablePair<String, String>>, TitanOperationStatus> artifactsRes = getGroupArtifactsPairs(groupInstance.getUniqueId());
+            if (artifactsRes.isRight()) {
+                TitanOperationStatus status = artifactsRes.right().value();
+                if (status != TitanOperationStatus.OK) {
+                    result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+                    return result;
+                }
+            } else {
+                List<String> artifactsUid = new ArrayList<>();
+                List<String> artifactsUUID = new ArrayList<>();
 
-			if (groupRes.isRight()) {
-				TitanOperationStatus status = groupRes.right().value();
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+                List<ImmutablePair<String, String>> list1 = artifactsRes.left().value();
+                if (list != null) {
+                    for (ImmutablePair<String, String> pair1 : list1) {
+                        String uid = pair1.left;
+                        String UUID = pair1.right;
+                        artifactsUid.add(uid);
+                        artifactsUUID.add(UUID);
+                    }
+                    groupInstance.setGroupInstanceArtifacts(artifactsUid);
+                    groupInstance.setGroupInstanceArtifactsUuid(artifactsUUID);
+                }
+            }
 
-			}
-			GroupDefinition groupDefinition = groupRes.left().value();
-			Either<Map<String, PropertyValueData>, TitanOperationStatus> groupInstancePropertyValuesRes = getAllGroupInstancePropertyValuesData(groupInstData);
-			if(groupInstancePropertyValuesRes.isRight()){
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(groupInstancePropertyValuesRes.right().value()));
-			}
-			buildGroupInstanceFromGroup(groupInstance, groupDefinition, groupInstancePropertyValuesRes.left().value());
-			/*
-			 * Either<List<GroupProperty>, TitanOperationStatus> groupInsPropStatus = getGroupInstanceProperties(groupInstance, groupDefinition); if (groupInsPropStatus.isRight()) {
-			 * 
-			 * return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(groupInsPropStatus.right().value())); }
-			 */
+            groupInstanceRes.add(groupInstance);
+            log.debug("GroupInstance {} was added to list ", groupInstance.getUniqueId());
+        }
 
-			Either<List<ImmutablePair<String, String>>, TitanOperationStatus> artifactsRes = getGroupArtifactsPairs(groupInstance.getUniqueId());
-			if (artifactsRes.isRight()) {
-				TitanOperationStatus status = artifactsRes.right().value();
-				if (status != TitanOperationStatus.OK) {
-					result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-					return result;
-				}
-			} else {
-				List<String> artifactsUid = new ArrayList<>();
-				List<String> artifactsUUID = new ArrayList<>();
+        result = Either.left(groupInstanceRes);
+        return result;
 
-				List<ImmutablePair<String, String>> list1 = artifactsRes.left().value();
-				if (list != null) {
-					for (ImmutablePair<String, String> pair1 : list1) {
-						String uid = pair1.left;
-						String UUID = pair1.right;
-						artifactsUid.add(uid);
-						artifactsUUID.add(UUID);
-					}
-					groupInstance.setGroupInstanceArtifacts(artifactsUid);
-					groupInstance.setGroupInstanceArtifactsUuid(artifactsUUID);
-				}
-			}
+    }
 
-			groupInstanceRes.add(groupInstance);
-			log.debug("GroupInstance {} was added to list ", groupInstance.getUniqueId());
-		}
+    @Override
+    public Either<Integer, StorageOperationStatus> increaseAndGetGroupInstancePropertyCounter(String instanceId) {
+        return propertyOperation.increaseAndGetObjInstancePropertyCounter(instanceId, NodeTypeEnum.GroupInstance);
+    }
 
-		result = Either.left(groupInstanceRes);
-		return result;
+    @Override
+    public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToGroupInstance(ComponentInstanceProperty groupInstanceProperty, String groupInstanceId, Integer index, boolean inTransaction) {
+        /// #RULES SUPPORT
+        /// Ignore rules received from client till support
+        groupInstanceProperty.setRules(null);
+        ///
+        ///
 
-	}
+        Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
 
-	@Override
-	public Either<Integer, StorageOperationStatus> increaseAndGetGroupInstancePropertyCounter(String groupInstanceId) {
-		Either<Integer, StorageOperationStatus> result = null;
+        try {
 
-		Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph();
-		if (graphResult.isRight()) {
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value()));
-			return result;
-		}
-		Either<TitanVertex, TitanOperationStatus> vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupInstanceId);
-		if (vertexService.isRight()) {
-			log.debug("failed to fetch vertex of resource instance for id = {}", groupInstanceId);
-			TitanOperationStatus status = vertexService.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value()));
-			return result;
-		}
-		Vertex vertex = vertexService.left().value();
+            Either<PropertyValueData, TitanOperationStatus> eitherStatus = addPropertyToGroupInstance(groupInstanceProperty, groupInstanceId, index);
 
-		VertexProperty<Object> vertexProperty = vertex.property(GraphPropertiesDictionary.PROPERTY_COUNTER.getProperty());
-		Integer counter = 0;
-		if (vertexProperty.isPresent()) {
-			if (vertexProperty.value() != null) {
-				counter = (Integer) vertexProperty.value();
-			}
-		}
+            if (eitherStatus.isRight()) {
+                log.error("Failed to add property value {} to resource instance {} in Graph. status is {}", groupInstanceProperty, groupInstanceId, eitherStatus.right().value().name());
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
+                return result;
+            } else {
+                PropertyValueData propertyValueData = eitherStatus.left().value();
 
-		counter++;
-		vertex.property(GraphPropertiesDictionary.PROPERTY_COUNTER.getProperty(), counter);
+                ComponentInstanceProperty propertyValueResult = propertyOperation.buildResourceInstanceProperty(propertyValueData, groupInstanceProperty);
+                log.debug("The returned GroupInstanceProperty is {}", propertyValueResult);
 
-		result = Either.left(counter);
-		return result;
+                Either<String, TitanOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(groupInstanceProperty.getPath(), groupInstanceProperty.getUniqueId(), groupInstanceProperty.getDefaultValue());
+                if (findDefaultValue.isRight()) {
+                    result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value()));
+                    return result;
+                }
+                String defaultValue = findDefaultValue.left().value();
+                propertyValueResult.setDefaultValue(defaultValue);
+                log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue);
 
-	}
+                result = Either.left(propertyValueResult);
+                return result;
+            }
+        }
 
-	@Override
-	public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToGroupInstance(ComponentInstanceProperty groupInstanceProperty, String groupInstanceId, Integer index, boolean inTransaction) {
-		/// #RULES SUPPORT
-		/// Ignore rules received from client till support
-		groupInstanceProperty.setRules(null);
-		///
-		///
+        finally {
+            if (!inTransaction) {
+                if (result == null || result.isRight()) {
+                    log.error("Going to execute rollback on graph.");
+                    titanGenericDao.rollback();
+                } else {
+                    log.debug("Going to execute commit on graph.");
+                    titanGenericDao.commit();
+                }
+            }
+        }
 
-		Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
+    }
 
-		try {
+    @Override
+    public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInGroupInstance(ComponentInstanceProperty gropuInstanceProperty, String groupInstanceId, boolean inTransaction) {
+        // TODO Auto-generated method stub
+        // change Propety class
+        return null;
+    }
 
-			Either<PropertyValueData, TitanOperationStatus> eitherStatus = addPropertyToGroupInstance(groupInstanceProperty, groupInstanceId, index);
+    public void generateCustomizationUUID(GroupInstance groupInstance) {
+        UUID uuid = UUID.randomUUID();
+        groupInstance.setCustomizationUUID(uuid.toString());
+    }
 
-			if (eitherStatus.isRight()) {
-				log.error("Failed to add property value {} to resource instance {} in Graph. status is {}", groupInstanceProperty, groupInstanceId, eitherStatus.right().value().name());
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
-				return result;
-			} else {
-				PropertyValueData propertyValueData = eitherStatus.left().value();
+    /**
+     * add property to resource instance
+     *
+     * @param index
+     * @return
+     */
+    public Either<PropertyValueData, TitanOperationStatus> addPropertyToGroupInstance(ComponentInstanceProperty groupInstanceProperty, String groupInstanceId, Integer index) {
 
-				ComponentInstanceProperty propertyValueResult = propertyOperation.buildResourceInstanceProperty(propertyValueData, groupInstanceProperty);
-				log.debug("The returned GroupInstanceProperty is {}", propertyValueResult);
+        Either<GroupInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupInstanceId, GroupInstanceData.class);
 
-				Either<String, TitanOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(groupInstanceProperty.getPath(), groupInstanceProperty.getUniqueId(), groupInstanceProperty.getDefaultValue());
-				if (findDefaultValue.isRight()) {
-					result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value()));
-					return result;
-				}
-				String defaultValue = findDefaultValue.left().value();
-				propertyValueResult.setDefaultValue(defaultValue);
-				log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue);
+        if (findResInstanceRes.isRight()) {
+            TitanOperationStatus status = findResInstanceRes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            return Either.right(status);
+        }
 
-				result = Either.left(propertyValueResult);
-				return result;
-			}
-		}
+        String propertyId = groupInstanceProperty.getUniqueId();
+        Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
 
-		finally {
-			if (false == inTransaction) {
-				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
-					titanGenericDao.rollback();
-				} else {
-					log.debug("Going to execute commit on graph.");
-					titanGenericDao.commit();
-				}
-			}
-		}
+        if (findPropertyDefRes.isRight()) {
+            TitanOperationStatus status = findPropertyDefRes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            return Either.right(status);
+        }
 
-	}
+        String valueUniqueUid = groupInstanceProperty.getValueUniqueUid();
+        if (valueUniqueUid == null) {
 
-	@Override
-	public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInGroupInstance(ComponentInstanceProperty gropuInstanceProperty, String groupInstanceId, boolean inTransaction) {
-		// TODO Auto-generated method stub
-		// change Propety class
-		return null;
-	}
+            PropertyData propertyData = findPropertyDefRes.left().value();
+            GroupInstanceData resourceInstanceData = findResInstanceRes.left().value();
 
-	public void generateCustomizationUUID(GroupInstance groupInstance) {
-		UUID uuid = UUID.randomUUID();
-		groupInstance.setCustomizationUUID(uuid.toString());
-	}
+            ImmutablePair<TitanOperationStatus, String> isPropertyValueExists = propertyOperation.findPropertyValue(groupInstanceId, propertyId);
+            if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) {
+                log.debug("The property {} already added to the resource instance {}", propertyId, groupInstanceId);
+                groupInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight());
+                Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance = updatePropertyOfGroupInstance(groupInstanceProperty, groupInstanceId);
+                if (updatePropertyOfResourceInstance.isRight()) {
+                    BeEcompErrorManager.getInstance().logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE, FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR);
+                    return Either.right(updatePropertyOfResourceInstance.right().value());
+                }
+                return Either.left(updatePropertyOfResourceInstance.left().value());
+            }
 
-	/**
-	 * add property to resource instance
-	 * 
-	 * @param index
-	 * @return
-	 */
-	public Either<PropertyValueData, TitanOperationStatus> addPropertyToGroupInstance(ComponentInstanceProperty groupInstanceProperty, String groupInstanceId, Integer index) {
+            if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) {
+                log.debug("After finding property value of {} on componenet instance {}", propertyId, groupInstanceId);
+                return Either.right(isPropertyValueExists.getLeft());
+            }
 
-		Either<GroupInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupInstanceId, GroupInstanceData.class);
+            String innerType = null;
 
-		if (findResInstanceRes.isRight()) {
-			TitanOperationStatus status = findResInstanceRes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			return Either.right(status);
-		}
+            PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
+            String propertyType = propDataDef.getType();
+            String value = groupInstanceProperty.getValue();
+            ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
 
-		String propertyId = groupInstanceProperty.getUniqueId();
-		Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
+            if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
+                SchemaDefinition def = propDataDef.getSchema();
+                if (def == null) {
+                    log.debug("Schema doesn't exists for property of type {}", type);
+                    return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+                }
+                PropertyDataDefinition propDef = def.getProperty();
+                if (propDef == null) {
+                    log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
+                    return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+                }
+                innerType = propDef.getType();
+            }
 
-		if (findPropertyDefRes.isRight()) {
-			TitanOperationStatus status = findPropertyDefRes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			return Either.right(status);
-		}
+            log.debug("Before validateAndUpdatePropertyValue");
+            Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
+            if (allDataTypes.isRight()) {
+                TitanOperationStatus status = allDataTypes.right().value();
+                BeEcompErrorManager.getInstance().logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE, FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + status, ErrorSeverity.ERROR);
+                return Either.right(status);
+            }
+            Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value());
+            log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid);
 
-		String valueUniqueUid = groupInstanceProperty.getValueUniqueUid();
-		if (valueUniqueUid == null) {
+            String newValue = value;
+            if (isValid.isRight()) {
+                Boolean res = isValid.right().value();
+                if (!res) {
+                    return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+                }
+            } else {
+                Object object = isValid.left().value();
+                if (object != null) {
+                    newValue = object.toString();
+                }
+            }
 
-			PropertyData propertyData = findPropertyDefRes.left().value();
-			GroupInstanceData resourceInstanceData = findResInstanceRes.left().value();
+            String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid(resourceInstanceData.getUniqueId(), index);
+            PropertyValueData propertyValueData = new PropertyValueData();
+            propertyValueData.setUniqueId(uniqueId);
+            propertyValueData.setValue(newValue);
 
-			ImmutablePair<TitanOperationStatus, String> isPropertyValueExists = propertyOperation.findPropertyValue(groupInstanceId, propertyId);
-			if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) {
-				log.debug("The property {} already added to the resource instance {}", propertyId, groupInstanceId);
-				groupInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight());
-				Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance = updatePropertyOfGroupInstance(groupInstanceProperty, groupInstanceId);
-				if (updatePropertyOfResourceInstance.isRight()) {
-					BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR);
-					return Either.right(updatePropertyOfResourceInstance.right().value());
-				}
-				return Either.left(updatePropertyOfResourceInstance.left().value());
-			}
+            log.debug("Before validateAndUpdateRules");
+            ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, groupInstanceProperty.getRules(), innerType, allDataTypes.left().value(), false);
+            log.debug("After validateAndUpdateRules. pair = {}", pair);
+            if (pair.getRight() != null && !pair.getRight()) {
+                BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), groupInstanceProperty.getName(), propertyType);
+                return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+            }
+            propertyOperation.addRulesToNewPropertyValue(propertyValueData, groupInstanceProperty, groupInstanceId);
 
-			if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) {
-				log.debug("After finding property value of {} on componenet instance {}", propertyId, groupInstanceId);
-				return Either.right(isPropertyValueExists.getLeft());
-			}
+            log.debug("Before adding property value to graph {}", propertyValueData);
+            Either<PropertyValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyValueData, PropertyValueData.class);
+            log.debug("After adding property value to graph {}", propertyValueData);
 
-			String innerType = null;
+            if (createNodeResult.isRight()) {
+                TitanOperationStatus operationStatus = createNodeResult.right().value();
+                return Either.right(operationStatus);
+            }
+            propertyValueData = createNodeResult.left().value();
 
-			PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
-			String propertyType = propDataDef.getType();
-			String value = groupInstanceProperty.getValue();
-			ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
+            Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null);
 
-			if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
-				SchemaDefinition def = propDataDef.getSchema();
-				if (def == null) {
-					log.debug("Schema doesn't exists for property of type {}", type);
-					return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-				}
-				PropertyDataDefinition propDef = def.getProperty();
-				if (propDef == null) {
-					log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
-					return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-				}
-				innerType = propDef.getType();
-			}
+            if (createRelResult.isRight()) {
+                TitanOperationStatus operationStatus = createRelResult.right().value();
+                log.error("Failed to associate property value {} to property {} in graph. status is {}", uniqueId, propertyId, operationStatus);
+                return Either.right(operationStatus);
+            }
 
-			log.debug("Before validateAndUpdatePropertyValue");
-			Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
-			if (allDataTypes.isRight()) {
-				TitanOperationStatus status = allDataTypes.right().value();
-				BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR);
-				return Either.right(status);
-			}
-			Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value());
-			log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid);
+            createRelResult = titanGenericDao.createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null);
 
-			String newValue = value;
-			if (isValid.isRight()) {
-				Boolean res = isValid.right().value();
-				if (res == false) {
-					return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-				}
-			} else {
-				Object object = isValid.left().value();
-				if (object != null) {
-					newValue = object.toString();
-				}
-			}
+            if (createRelResult.isRight()) {
+                TitanOperationStatus operationStatus = createRelResult.right().value();
+                log.error("Failed to associate resource instance {} property value {} in graph. status is {}", groupInstanceId, uniqueId, operationStatus);
+                return Either.right(operationStatus);
+            }
 
-			String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid(resourceInstanceData.getUniqueId(), index);
-			PropertyValueData propertyValueData = new PropertyValueData();
-			propertyValueData.setUniqueId(uniqueId);
-			propertyValueData.setValue(newValue);
+            return Either.left(propertyValueData);
+        } else {
+            log.error("property value already exists.");
+            return Either.right(TitanOperationStatus.ALREADY_EXIST);
+        }
 
-			log.debug("Before validateAndUpdateRules");
-			ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, groupInstanceProperty.getRules(), innerType, allDataTypes.left().value(), false);
-			log.debug("After validateAndUpdateRules. pair = {}", pair);
-			if (pair.getRight() != null && pair.getRight() == false) {
-				BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), groupInstanceProperty.getName(), propertyType);
-				return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-			}
-			propertyOperation.addRulesToNewPropertyValue(propertyValueData, groupInstanceProperty, groupInstanceId);
+    }
 
-			log.debug("Before adding property value to graph {}", propertyValueData);
-			Either<PropertyValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyValueData, PropertyValueData.class);
-			log.debug("After adding property value to graph {}", propertyValueData);
+    /**
+     * update value of attribute on resource instance
+     *
+     * @return
+     */
+    public Either<PropertyValueData, TitanOperationStatus> updatePropertyOfGroupInstance(ComponentInstanceProperty groupInstanceProerty, String groupInstanceId) {
 
-			if (createNodeResult.isRight()) {
-				TitanOperationStatus operationStatus = createNodeResult.right().value();
-				return Either.right(operationStatus);
-			}
-			propertyValueData = createNodeResult.left().value();
+        Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>();
+        UpdateDataContainer<PropertyData, PropertyValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.PROPERTY_IMPL, (() -> PropertyData.class), (() -> PropertyValueData.class), NodeTypeEnum.Property,
+                NodeTypeEnum.PropertyValue);
 
-			Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null);
+        preUpdateElementOfResourceInstanceValidations(updateDataContainer, groupInstanceProerty, groupInstanceId, errorWrapper);
+        if (!errorWrapper.isEmpty()) {
+            return Either.right(errorWrapper.getInnerElement());
+        }
 
-			if (createRelResult.isRight()) {
-				TitanOperationStatus operationStatus = createRelResult.right().value();
-				log.error("Failed to associate property value {} to property {} in graph. status is {}", uniqueId, propertyId, operationStatus);
-				return Either.right(operationStatus);
-			}
+        else {
+            String value = groupInstanceProerty.getValue();
+            // Specific Validation Logic
+            PropertyData propertyData = updateDataContainer.getDataWrapper().getInnerElement();
 
-			createRelResult = titanGenericDao.createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null);
+            String innerType = null;
 
-			if (createRelResult.isRight()) {
-				TitanOperationStatus operationStatus = createRelResult.right().value();
-				log.error("Failed to associate resource instance {} property value {} in graph. status is {}", groupInstanceId, uniqueId, operationStatus);
-				return Either.right(operationStatus);
-			}
+            PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
+            String propertyType = propDataDef.getType();
+            ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
+            log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType);
 
-			return Either.left(propertyValueData);
-		} else {
-			log.error("property value already exists.");
-			return Either.right(TitanOperationStatus.ALREADY_EXIST);
-		}
+            if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
+                SchemaDefinition def = propDataDef.getSchema();
+                if (def == null) {
+                    log.debug("Schema doesn't exists for property of type {}", type);
+                    return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+                }
+                PropertyDataDefinition propDef = def.getProperty();
+                if (propDef == null) {
+                    log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
+                    return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+                }
+                innerType = propDef.getType();
+            }
+            // Specific Update Logic
+            Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
+            if (allDataTypes.isRight()) {
+                TitanOperationStatus status = allDataTypes.right().value();
+                BeEcompErrorManager.getInstance().logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE, FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + status, ErrorSeverity.ERROR);
+                return Either.right(status);
+            }
+            Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value());
 
-	}
-
-	/**
-	 * update value of attribute on resource instance
-	 * 
-	 * @return
-	 */
-	public Either<PropertyValueData, TitanOperationStatus> updatePropertyOfGroupInstance(ComponentInstanceProperty groupInstanceProerty, String groupInstanceId) {
-
-		Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>();
-		UpdateDataContainer<PropertyData, PropertyValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.PROPERTY_IMPL, (() -> PropertyData.class), (() -> PropertyValueData.class), NodeTypeEnum.Property,
-				NodeTypeEnum.PropertyValue);
-
-		preUpdateElementOfResourceInstanceValidations(updateDataContainer, groupInstanceProerty, groupInstanceId, errorWrapper);
-		if (!errorWrapper.isEmpty()) {
-			return Either.right(errorWrapper.getInnerElement());
-		}
-
-		else {
-			String value = groupInstanceProerty.getValue();
-			// Specific Validation Logic
-			PropertyData propertyData = updateDataContainer.getDataWrapper().getInnerElement();
-
-			String innerType = null;
-
-			PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
-			String propertyType = propDataDef.getType();
-			ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
-			log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType);
+            String newValue = value;
+            if (isValid.isRight()) {
+                Boolean res = isValid.right().value();
+                if (!res) {
+                    return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+                }
+            } else {
+                Object object = isValid.left().value();
+                if (object != null) {
+                    newValue = object.toString();
+                }
+            }
+            PropertyValueData propertyValueData = updateDataContainer.getValueDataWrapper().getInnerElement();
+            log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue);
+            propertyValueData.setValue(newValue);
 
-			if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
-				SchemaDefinition def = propDataDef.getSchema();
-				if (def == null) {
-					log.debug("Schema doesn't exists for property of type {}", type);
-					return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-				}
-				PropertyDataDefinition propDef = def.getProperty();
-				if (propDef == null) {
-					log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
-					return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-				}
-				innerType = propDef.getType();
-			}
-			// Specific Update Logic
-			Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
-			if (allDataTypes.isRight()) {
-				TitanOperationStatus status = allDataTypes.right().value();
-				BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR);
-				return Either.right(status);
-			}
-			Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value());
+            ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, groupInstanceProerty.getRules(), innerType, allDataTypes.left().value(), true);
+            if (pair.getRight() != null && !pair.getRight()) {
+                BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), groupInstanceProerty.getName(), propertyType);
+                return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+            }
+            propertyOperation.updateRulesInPropertyValue(propertyValueData, groupInstanceProerty, groupInstanceId);
 
-			String newValue = value;
-			if (isValid.isRight()) {
-				Boolean res = isValid.right().value();
-				if (res == false) {
-					return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-				}
-			} else {
-				Object object = isValid.left().value();
-				if (object != null) {
-					newValue = object.toString();
-				}
-			}
-			PropertyValueData propertyValueData = updateDataContainer.getValueDataWrapper().getInnerElement();
-			log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue);
-			propertyValueData.setValue(newValue);
+            Either<PropertyValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class);
+            if (updateRes.isRight()) {
+                TitanOperationStatus status = updateRes.right().value();
+                return Either.right(status);
+            } else {
+                return Either.left(updateRes.left().value());
+            }
+        }
 
-			ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, groupInstanceProerty.getRules(), innerType, allDataTypes.left().value(), true);
-			if (pair.getRight() != null && pair.getRight() == false) {
-				BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), groupInstanceProerty.getName(), propertyType);
-				return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-			}
-			propertyOperation.updateRulesInPropertyValue(propertyValueData, groupInstanceProerty, groupInstanceId);
+    }
 
-			Either<PropertyValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class);
-			if (updateRes.isRight()) {
-				TitanOperationStatus status = updateRes.right().value();
-				return Either.right(status);
-			} else {
-				return Either.left(updateRes.left().value());
-			}
-		}
+    private static final class UpdateDataContainer<SomeData, SomeValueData> {
+        final Wrapper<SomeValueData> valueDataWrapper;
+        final Wrapper<SomeData> dataWrapper;
+        final GraphEdgeLabels graphEdge;
+        final Supplier<Class<SomeData>> someDataClassGen;
+        final Supplier<Class<SomeValueData>> someValueDataClassGen;
+        final NodeTypeEnum nodeType;
+        final NodeTypeEnum nodeTypeValue;
 
-	}
+        private UpdateDataContainer(GraphEdgeLabels graphEdge, Supplier<Class<SomeData>> someDataClassGen, Supplier<Class<SomeValueData>> someValueDataClassGen, NodeTypeEnum nodeType, NodeTypeEnum nodeTypeValue) {
+            super();
+            this.valueDataWrapper = new Wrapper<>();
+            this.dataWrapper = new Wrapper<>();
+            this.graphEdge = graphEdge;
+            this.someDataClassGen = someDataClassGen;
+            this.someValueDataClassGen = someValueDataClassGen;
+            this.nodeType = nodeType;
+            this.nodeTypeValue = nodeTypeValue;
+        }
 
-	private static final class UpdateDataContainer<SomeData, SomeValueData> {
-		final Wrapper<SomeValueData> valueDataWrapper;
-		final Wrapper<SomeData> dataWrapper;
-		final GraphEdgeLabels graphEdge;
-		final Supplier<Class<SomeData>> someDataClassGen;
-		final Supplier<Class<SomeValueData>> someValueDataClassGen;
-		final NodeTypeEnum nodeType;
-		final NodeTypeEnum nodeTypeValue;
+        public Wrapper<SomeValueData> getValueDataWrapper() {
+            return valueDataWrapper;
+        }
 
-		private UpdateDataContainer(GraphEdgeLabels graphEdge, Supplier<Class<SomeData>> someDataClassGen, Supplier<Class<SomeValueData>> someValueDataClassGen, NodeTypeEnum nodeType, NodeTypeEnum nodeTypeValue) {
-			super();
-			this.valueDataWrapper = new Wrapper<>();
-			this.dataWrapper = new Wrapper<>();
-			this.graphEdge = graphEdge;
-			this.someDataClassGen = someDataClassGen;
-			this.someValueDataClassGen = someValueDataClassGen;
-			this.nodeType = nodeType;
-			this.nodeTypeValue = nodeTypeValue;
-		}
+        public Wrapper<SomeData> getDataWrapper() {
+            return dataWrapper;
+        }
 
-		public Wrapper<SomeValueData> getValueDataWrapper() {
-			return valueDataWrapper;
-		}
+        public GraphEdgeLabels getGraphEdge() {
+            return graphEdge;
+        }
 
-		public Wrapper<SomeData> getDataWrapper() {
-			return dataWrapper;
-		}
+        public Supplier<Class<SomeData>> getSomeDataClassGen() {
+            return someDataClassGen;
+        }
 
-		public GraphEdgeLabels getGraphEdge() {
-			return graphEdge;
-		}
+        public Supplier<Class<SomeValueData>> getSomeValueDataClassGen() {
+            return someValueDataClassGen;
+        }
 
-		public Supplier<Class<SomeData>> getSomeDataClassGen() {
-			return someDataClassGen;
-		}
+        public NodeTypeEnum getNodeType() {
+            return nodeType;
+        }
 
-		public Supplier<Class<SomeValueData>> getSomeValueDataClassGen() {
-			return someValueDataClassGen;
-		}
+        public NodeTypeEnum getNodeTypeValue() {
+            return nodeTypeValue;
+        }
+    }
 
-		public NodeTypeEnum getNodeType() {
-			return nodeType;
-		}
+    private <SomeData extends GraphNode, SomeValueData extends GraphNode> void preUpdateElementOfResourceInstanceValidations(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
+            String resourceInstanceId, Wrapper<TitanOperationStatus> errorWrapper) {
 
-		public NodeTypeEnum getNodeTypeValue() {
-			return nodeTypeValue;
-		}
-	}
+        if (errorWrapper.isEmpty()) {
+            // Verify VFC instance Exist
+            validateGIExist(resourceInstanceId, errorWrapper);
+        }
 
-	private <SomeData extends GraphNode, SomeValueData extends GraphNode> void preUpdateElementOfResourceInstanceValidations(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
-			String resourceInstanceId, Wrapper<TitanOperationStatus> errorWrapper) {
+        if (errorWrapper.isEmpty()) {
+            // Example: Verify Property connected to VFC exist
+            validateElementConnectedToComponentExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
+        }
 
-		if (errorWrapper.isEmpty()) {
-			// Verify VFC instance Exist
-			validateGIExist(resourceInstanceId, errorWrapper);
-		}
+        if (errorWrapper.isEmpty()) {
+            // Example: Verify PropertyValue connected to VFC Instance exist
+            validateElementConnectedToComponentInstanceExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
+        }
 
-		if (errorWrapper.isEmpty()) {
-			// Example: Verify Property connected to VFC exist
-			validateElementConnectedToComponentExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
-		}
+        if (errorWrapper.isEmpty()) {
+            // Example: Verify PropertyValue connected Property
+            validateElementConnectedToInstance(updateDataContainer, resourceInstanceProerty, errorWrapper);
+        }
+    }
 
-		if (errorWrapper.isEmpty()) {
-			// Example: Verify PropertyValue connected to VFC Instance exist
-			validateElementConnectedToComponentInstanceExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
-		}
+    private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToInstance(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
+            Wrapper<TitanOperationStatus> errorWrapper) {
+        Either<ImmutablePair<SomeData, GraphEdge>, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), resourceInstanceProerty.getValueUniqueUid(),
+                updateDataContainer.getGraphEdge(), updateDataContainer.getNodeType(), updateDataContainer.getSomeDataClassGen().get());
 
-		if (errorWrapper.isEmpty()) {
-			// Example: Verify PropertyValue connected Property
-			validateElementConnectedToInstance(updateDataContainer, resourceInstanceProerty, errorWrapper);
-		}
-	}
+        if (child.isRight()) {
+            TitanOperationStatus status = child.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            errorWrapper.setInnerElement(status);
 
-	private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToInstance(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
-			Wrapper<TitanOperationStatus> errorWrapper) {
-		Either<ImmutablePair<SomeData, GraphEdge>, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), resourceInstanceProerty.getValueUniqueUid(),
-				updateDataContainer.getGraphEdge(), updateDataContainer.getNodeType(), updateDataContainer.getSomeDataClassGen().get());
+        } else {
+            updateDataContainer.getDataWrapper().setInnerElement(child.left().value().left);
+        }
+    }
 
-		if (child.isRight()) {
-			TitanOperationStatus status = child.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			errorWrapper.setInnerElement(status);
+    private <SomeValueData extends GraphNode, SomeData extends GraphNode> void validateElementConnectedToComponentInstanceExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer,
+            IComponentInstanceConnectedElement resourceInstanceProerty, Wrapper<TitanOperationStatus> errorWrapper) {
+        String valueUniqueUid = resourceInstanceProerty.getValueUniqueUid();
+        if (valueUniqueUid == null) {
+            errorWrapper.setInnerElement(TitanOperationStatus.INVALID_ID);
+        } else {
+            Either<SomeValueData, TitanOperationStatus> findPropertyValueRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), valueUniqueUid, updateDataContainer.getSomeValueDataClassGen().get());
+            if (findPropertyValueRes.isRight()) {
+                TitanOperationStatus status = findPropertyValueRes.right().value();
+                if (status == TitanOperationStatus.NOT_FOUND) {
+                    status = TitanOperationStatus.INVALID_ID;
+                }
+                errorWrapper.setInnerElement(status);
+            } else {
+                updateDataContainer.getValueDataWrapper().setInnerElement(findPropertyValueRes.left().value());
+            }
+        }
+    }
 
-		} else {
-			updateDataContainer.getDataWrapper().setInnerElement(child.left().value().left);
-		}
-	}
+    private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToComponentExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer,
+            IComponentInstanceConnectedElement resourceInstanceElementConnected, Wrapper<TitanOperationStatus> errorWrapper) {
+        String uniqueId = resourceInstanceElementConnected.getUniqueId();
+        Either<SomeData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeType()), uniqueId, updateDataContainer.getSomeDataClassGen().get());
 
-	private <SomeValueData extends GraphNode, SomeData extends GraphNode> void validateElementConnectedToComponentInstanceExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer,
-			IComponentInstanceConnectedElement resourceInstanceProerty, Wrapper<TitanOperationStatus> errorWrapper) {
-		String valueUniqueUid = resourceInstanceProerty.getValueUniqueUid();
-		if (valueUniqueUid == null) {
-			errorWrapper.setInnerElement(TitanOperationStatus.INVALID_ID);
-		} else {
-			Either<SomeValueData, TitanOperationStatus> findPropertyValueRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), valueUniqueUid, updateDataContainer.getSomeValueDataClassGen().get());
-			if (findPropertyValueRes.isRight()) {
-				TitanOperationStatus status = findPropertyValueRes.right().value();
-				if (status == TitanOperationStatus.NOT_FOUND) {
-					status = TitanOperationStatus.INVALID_ID;
-				}
-				errorWrapper.setInnerElement(status);
-			} else {
-				updateDataContainer.getValueDataWrapper().setInnerElement(findPropertyValueRes.left().value());
-			}
-		}
-	}
+        if (findPropertyDefRes.isRight()) {
+            TitanOperationStatus status = findPropertyDefRes.right().value();
+            errorWrapper.setInnerElement(status);
+        }
+    }
 
-	private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToComponentExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer,
-			IComponentInstanceConnectedElement resourceInstanceElementConnected, Wrapper<TitanOperationStatus> errorWrapper) {
-		String uniqueId = resourceInstanceElementConnected.getUniqueId();
-		Either<SomeData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeType()), uniqueId, updateDataContainer.getSomeDataClassGen().get());
+    private void validateGIExist(String resourceInstanceId, Wrapper<TitanOperationStatus> errorWrapper) {
+        validateGIExist(resourceInstanceId, null, errorWrapper);
+    }
 
-		if (findPropertyDefRes.isRight()) {
-			TitanOperationStatus status = findPropertyDefRes.right().value();
-			errorWrapper.setInnerElement(status);
-		}
-	}
+    private void validateGIExist(String resourceInstanceId, Wrapper<GroupInstanceData> compInsDataWrapper, Wrapper<TitanOperationStatus> errorWrapper) {
+        validateElementExistInGraph(resourceInstanceId, NodeTypeEnum.GroupInstance, () -> GroupInstanceData.class, compInsDataWrapper, errorWrapper);
+    }
 
-	private void validateGIExist(String resourceInstanceId, Wrapper<TitanOperationStatus> errorWrapper) {
-		validateGIExist(resourceInstanceId, null, errorWrapper);
-	}
+    public <ElementData extends GraphNode> void validateElementExistInGraph(String elementUniqueId, NodeTypeEnum elementNodeType, Supplier<Class<ElementData>> elementClassGen, Wrapper<ElementData> elementDataWrapper,
+            Wrapper<TitanOperationStatus> errorWrapper) {
+        Either<ElementData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(elementNodeType), elementUniqueId, elementClassGen.get());
+        if (findResInstanceRes.isRight()) {
+            TitanOperationStatus status = findResInstanceRes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            errorWrapper.setInnerElement(status);
+        } else {
+            if (elementDataWrapper != null) {
+                elementDataWrapper.setInnerElement(findResInstanceRes.left().value());
+            }
+        }
+    }
 
-	private void validateGIExist(String resourceInstanceId, Wrapper<GroupInstanceData> compInsDataWrapper, Wrapper<TitanOperationStatus> errorWrapper) {
-		validateElementExistInGraph(resourceInstanceId, NodeTypeEnum.GroupInstance, () -> GroupInstanceData.class, compInsDataWrapper, errorWrapper);
-	}
+    private void buildGroupInstanceFromGroup(GroupInstance groupInstance, GroupDefinition groupDefinition, Map<String, PropertyValueData> groupInstancePropertyValues) {
 
-	public <ElementData extends GraphNode> void validateElementExistInGraph(String elementUniqueId, NodeTypeEnum elementNodeType, Supplier<Class<ElementData>> elementClassGen, Wrapper<ElementData> elementDataWrapper,
-			Wrapper<TitanOperationStatus> errorWrapper) {
-		Either<ElementData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(elementNodeType), elementUniqueId, elementClassGen.get());
-		if (findResInstanceRes.isRight()) {
-			TitanOperationStatus status = findResInstanceRes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			errorWrapper.setInnerElement(status);
-		} else {
-			if (elementDataWrapper != null) {
-				elementDataWrapper.setInnerElement(findResInstanceRes.left().value());
-			}
-		}
-	}
+        groupInstance.setGroupName(groupDefinition.getName());
+        groupInstance.setInvariantUUID(groupDefinition.getInvariantUUID());
+        groupInstance.setDescription(groupDefinition.getDescription());
+        groupInstance.setVersion(groupDefinition.getVersion());
+        groupInstance.setArtifacts(groupDefinition.getArtifacts());
+        groupInstance.setArtifactsUuid(groupDefinition.getArtifactsUuid());
+        groupInstance.setType(groupDefinition.getType());
+        groupInstance.setGroupUUID(groupDefinition.getGroupUUID());
 
-	private void buildGroupInstanceFromGroup(GroupInstance groupInstance, GroupDefinition groupDefinition, Map<String, PropertyValueData> groupInstancePropertyValues) {
+        List<GroupInstanceProperty> groupInstanceProperties = groupDefinition.convertToGroupProperties()
+                //converts List of GroupProperties to List of GroupInstanceProperties and updates it with group instance property data
+                .stream().map(p -> getUpdatedConvertedProperty(p, groupInstancePropertyValues)).collect(Collectors.toList());
+        groupInstance.convertFromGroupInstancesProperties(groupInstanceProperties);
+    }
 
-		groupInstance.setGroupName(groupDefinition.getName());
-		groupInstance.setInvariantUUID(groupDefinition.getInvariantUUID());
-		groupInstance.setDescription(groupDefinition.getDescription());
-		groupInstance.setVersion(groupDefinition.getVersion());
-		groupInstance.setArtifacts(groupDefinition.getArtifacts());
-		groupInstance.setArtifactsUuid(groupDefinition.getArtifactsUuid());
-		groupInstance.setType(groupDefinition.getType());
-		groupInstance.setGroupUUID(groupDefinition.getGroupUUID());
+    private GroupInstanceProperty getUpdatedConvertedProperty(GroupProperty groupProperty,  Map<String, PropertyValueData> groupInstancePropertyValues){
 
-		List<GroupInstanceProperty> groupInstanceProperties = groupDefinition.convertToGroupProperties()
-				//converts List of GroupProperties to List of GroupInstanceProperties and updates it with group instance property data
-				.stream().map(p -> getUpdatedConvertedProperty(p, groupInstancePropertyValues)).collect(Collectors.toList());
-		groupInstance.convertFromGroupInstancesProperties(groupInstanceProperties);
-	}
-	
-	private GroupInstanceProperty getUpdatedConvertedProperty(GroupProperty groupProperty,  Map<String, PropertyValueData> groupInstancePropertyValues){
+        GroupInstanceProperty updatedProperty = new GroupInstanceProperty(groupProperty, groupProperty.getValue());
+        if(!MapUtils.isEmpty(groupInstancePropertyValues) && groupInstancePropertyValues.containsKey(groupProperty.getName())){
+            PropertyValueData groupInstancePropertyValue = groupInstancePropertyValues.get(groupProperty.getName());
+            updatedProperty.setValue(groupInstancePropertyValue.getValue());
+            updatedProperty.setValueUniqueUid(groupInstancePropertyValue.getUniqueId());
+        }
+        return updatedProperty;
+    }
 
-		GroupInstanceProperty updatedProperty = new GroupInstanceProperty(groupProperty, groupProperty.getValue());
-		if(!MapUtils.isEmpty(groupInstancePropertyValues) && groupInstancePropertyValues.containsKey(groupProperty.getName())){
-			PropertyValueData groupInstancePropertyValue = groupInstancePropertyValues.get(groupProperty.getName());
-			updatedProperty.setValue(groupInstancePropertyValue.getValue());
-			updatedProperty.setValueUniqueUid(groupInstancePropertyValue.getUniqueId());
-		}
-		return updatedProperty;
-	}
+    private Either<List<ImmutablePair<String, String>>, TitanOperationStatus> getGroupArtifactsPairs(String groupUniqueId) {
 
-	private Either<List<ImmutablePair<String, String>>, TitanOperationStatus> getGroupArtifactsPairs(String groupUniqueId) {
+        Either<List<ImmutablePair<String, String>>, TitanOperationStatus> result = null;
 
-		Either<List<ImmutablePair<String, String>>, TitanOperationStatus> result = null;
+        Either<List<ImmutablePair<ArtifactData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupUniqueId, GraphEdgeLabels.GROUP_ARTIFACT_REF,
+                NodeTypeEnum.ArtifactRef, ArtifactData.class);
+        if (childrenNodes.isRight()) {
+            TitanOperationStatus status = childrenNodes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.OK;
+            }
+            result = Either.right(status);
 
-		Either<List<ImmutablePair<ArtifactData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupUniqueId, GraphEdgeLabels.GROUP_ARTIFACT_REF,
-				NodeTypeEnum.ArtifactRef, ArtifactData.class);
-		if (childrenNodes.isRight()) {
-			TitanOperationStatus status = childrenNodes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.OK;
-			}
-			result = Either.right(status);
+        } else {
 
-		} else {
+            List<ImmutablePair<String, String>> artifactsList = new ArrayList<>();
+            List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenNodes.left().value();
+            if (list != null) {
+                for (ImmutablePair<ArtifactData, GraphEdge> pair : list) {
+                    ArtifactData artifactData = pair.getKey();
+                    String uniqueId = artifactData.getArtifactDataDefinition().getUniqueId();
+                    String UUID = artifactData.getArtifactDataDefinition().getArtifactUUID();
+                    ImmutablePair<String, String> artifact = new ImmutablePair<>(uniqueId, UUID);
+                    artifactsList.add(artifact);
+                }
+            }
 
-			List<ImmutablePair<String, String>> artifactsList = new ArrayList<>();
-			List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenNodes.left().value();
-			if (list != null) {
-				for (ImmutablePair<ArtifactData, GraphEdge> pair : list) {
-					ArtifactData artifactData = pair.getKey();
-					String uniqueId = artifactData.getArtifactDataDefinition().getUniqueId();
-					String UUID = artifactData.getArtifactDataDefinition().getArtifactUUID();
-					ImmutablePair<String, String> artifact = new ImmutablePair<String, String>(uniqueId, UUID);
-					artifactsList.add(artifact);
-				}
-			}
+            log.debug("The artifacts list related to group {} is {}",groupUniqueId,artifactsList);
+            result = Either.left(artifactsList);
+        }
 
-			log.debug("The artifacts list related to group {} is {}",groupUniqueId,artifactsList);
-			result = Either.left(artifactsList);
-		}
+        return result;
 
-		return result;
+    }
 
-	}
+    @Override
+    public StorageOperationStatus dissociateAndAssociateGroupsInstanceFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) {
 
-	@Override
-	public StorageOperationStatus dissociateAndAssociateGroupsInstanceFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) {
+        return this.dissociateAndAssociateGroupsInstanceFromArtifactOnGraph(componentId, componentTypeEnum, oldArtifactId, newArtifact);
 
-		return this.dissociateAndAssociateGroupsInstanceFromArtifactOnGraph(componentId, componentTypeEnum, oldArtifactId, newArtifact);
+    }
 
-	}
+    private StorageOperationStatus dissociateAndAssociateGroupsInstanceFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) {
 
-	private StorageOperationStatus dissociateAndAssociateGroupsInstanceFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) {
+        Either<List<GroupInstance>, StorageOperationStatus> allGroupsFromGraph = getAllGroupInstances(componentId, componentTypeEnum);
+        if (allGroupsFromGraph.isRight()) {
+            return allGroupsFromGraph.right().value();
+        }
 
-		Either<List<GroupInstance>, StorageOperationStatus> allGroupsFromGraph = getAllGroupInstances(componentId, componentTypeEnum);
-		if (allGroupsFromGraph.isRight()) {
-			StorageOperationStatus status = allGroupsFromGraph.right().value();
-			return status;
-		}
+        List<GroupInstance> allGroups = allGroupsFromGraph.left().value();
+        if (allGroups == null || allGroups.isEmpty()) {
+            return StorageOperationStatus.OK;
+        }
 
-		List<GroupInstance> allGroups = allGroupsFromGraph.left().value();
-		if (allGroups == null || allGroups.isEmpty()) {
-			return StorageOperationStatus.OK;
-		}
+        // Find all groups which contains this artifact id
+        List<GroupInstance> associatedGroups = allGroups.stream().filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(oldArtifactId)).collect(Collectors.toList());
 
-		// Find all groups which contains this artifact id
-		List<GroupInstance> associatedGroups = allGroups.stream().filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(oldArtifactId)).collect(Collectors.toList());
+        if (associatedGroups != null && !associatedGroups.isEmpty()) {
 
-		if (associatedGroups != null && false == associatedGroups.isEmpty()) {
+            log.debug("The groups {} contains the artifact {}",associatedGroups.stream().map(GroupInstanceDataDefinition::getName).collect(Collectors.toList()),oldArtifactId);
 
-			log.debug("The groups {} contains the artifact {}",associatedGroups.stream().map(p -> p.getName()).collect(Collectors.toList()),oldArtifactId);
+            UniqueIdData oldArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, oldArtifactId);
+            UniqueIdData newArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, newArtifact.getArtifactDataDefinition().getUniqueId());
+            Map<String, Object> props = new HashMap<>();
+            props.put(GraphPropertiesDictionary.NAME.getProperty(), newArtifactData.getLabel());
 
-			UniqueIdData oldArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, oldArtifactId);
-			UniqueIdData newArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, newArtifact.getArtifactDataDefinition().getUniqueId());
-			Map<String, Object> props = new HashMap<String, Object>();
-			props.put(GraphPropertiesDictionary.NAME.getProperty(), newArtifactData.getLabel());
+            for (GroupInstance groupDefinition : associatedGroups) {
+                UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.GroupInstance, groupDefinition.getUniqueId());
 
-			for (GroupInstance groupDefinition : associatedGroups) {
-				UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.GroupInstance, groupDefinition.getUniqueId());
+                Either<GraphRelation, TitanOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, oldArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF);
+                log.trace("After dissociate group {} from artifact {}", groupDefinition.getName(), oldArtifactId);
+                if (deleteRelation.isRight()) {
+                    TitanOperationStatus status = deleteRelation.right().value();
+                    if (status == TitanOperationStatus.NOT_FOUND) {
+                        status = TitanOperationStatus.INVALID_ID;
+                    }
+                    return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+                }
 
-				Either<GraphRelation, TitanOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, oldArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF);
-				log.trace("After dissociate group {} from artifact {}", groupDefinition.getName(), oldArtifactId);
-				if (deleteRelation.isRight()) {
-					TitanOperationStatus status = deleteRelation.right().value();
-					if (status == TitanOperationStatus.NOT_FOUND) {
-						status = TitanOperationStatus.INVALID_ID;
-					}
-					return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-				}
+                Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(groupData, newArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF, props);
+                log.trace("After associate group {} to artifact {}", groupDefinition.getName(), newArtifact.getUniqueIdKey());
+                if (createRelation.isRight()) {
+                    TitanOperationStatus status = createRelation.right().value();
+                    if (status == TitanOperationStatus.NOT_FOUND) {
+                        status = TitanOperationStatus.INVALID_ID;
+                    }
+                    return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+                }
+            }
 
-				Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(groupData, newArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF, props);
-				log.trace("After associate group {} to artifact {}", groupDefinition.getName(), newArtifact.getUniqueIdKey());
-				if (createRelation.isRight()) {
-					TitanOperationStatus status = createRelation.right().value();
-					if (status == TitanOperationStatus.NOT_FOUND) {
-						status = TitanOperationStatus.INVALID_ID;
-					}
-					return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-				}
-			}
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		}
-		return StorageOperationStatus.OK;
-	}
+    private Either<Map<String, PropertyValueData>, TitanOperationStatus> getAllGroupInstancePropertyValuesData(GroupInstanceData groupInstData) {
 
-	private Either<Map<String, PropertyValueData>, TitanOperationStatus> getAllGroupInstancePropertyValuesData(GroupInstanceData groupInstData) {
-		
-		Either<Map<String, PropertyValueData>, TitanOperationStatus> result = null;
-		try{
-			Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> getPropertyValueChildrenRes = 
-					titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), groupInstData.getUniqueId(), GraphEdgeLabels.PROPERTY_VALUE,
-							NodeTypeEnum.PropertyValue, PropertyValueData.class, true);
-			if(getPropertyValueChildrenRes.isRight()){
-				TitanOperationStatus status = getPropertyValueChildrenRes.right().value();
-				log.debug("Failed to fetch property value nodes for group instance {}. Status is {}. ", groupInstData.getName(), status);
-				if(status == TitanOperationStatus.NOT_FOUND){
-					result = Either.left(null);
-				}else{
-					result = Either.right(status);
-				}
-			}else{
-				result = Either.left(getPropertyValueChildrenRes.left().value().stream()
-						.collect(Collectors.toMap(pair->(String)(pair.getRight().getProperties().get(GraphPropertiesDictionary.PROPERTY_NAME.getProperty())), pair->pair.getLeft())));
-			}
-		} catch(Exception e){
-			log.debug("The Exception occured during fetch group instance () property values. The message is {}. ", groupInstData.getName(), e.getMessage(), e);
-			if(result == null){
-				result = Either.right(TitanOperationStatus.GENERAL_ERROR);
-			}
-		}
-		return result;
-	}
+        Either<Map<String, PropertyValueData>, TitanOperationStatus> result = null;
+        try{
+            Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> getPropertyValueChildrenRes =
+                    titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), groupInstData.getUniqueId(), GraphEdgeLabels.PROPERTY_VALUE,
+                            NodeTypeEnum.PropertyValue, PropertyValueData.class, true);
+            if(getPropertyValueChildrenRes.isRight()){
+                TitanOperationStatus status = getPropertyValueChildrenRes.right().value();
+                log.debug("Failed to fetch property value nodes for group instance {}. Status is {}. ", groupInstData.getName(), status);
+                if(status == TitanOperationStatus.NOT_FOUND){
+                    result = Either.left(null);
+                }else{
+                    result = Either.right(status);
+                }
+            }else{
+                result = Either.left(getPropertyValueChildrenRes.left().value().stream()
+                        .collect(Collectors.toMap(pair->(String)(pair.getRight().getProperties().get(GraphPropertiesDictionary.PROPERTY_NAME.getProperty())), ImmutablePair::getLeft)));
+            }
+        } catch(Exception e){
+            log.debug("The Exception occured during fetch group instance () property values. The message is {}. ", groupInstData.getName(), e.getMessage(), e);
+            if(result == null){
+                result = Either.right(TitanOperationStatus.GENERAL_ERROR);
+            }
+        }
+        return result;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java
index 77e7ba1..1187837 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java
@@ -20,549 +20,600 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.dao.utils.MapUtil;
+import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.GroupProperty;
-import org.openecomp.sdc.be.model.GroupTypeDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
+import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation;
+import org.openecomp.sdc.be.model.operations.StorageException;
 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
-import org.openecomp.sdc.be.resources.data.ArtifactData;
-import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
-import org.openecomp.sdc.be.resources.data.GroupData;
-import org.openecomp.sdc.be.resources.data.GroupTypeData;
-import org.openecomp.sdc.be.resources.data.PropertyData;
-import org.openecomp.sdc.be.resources.data.PropertyValueData;
-import org.openecomp.sdc.be.resources.data.UniqueIdData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.be.resources.data.*;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
-import fj.data.Either;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
-@Component("group-operation")
+import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import static org.springframework.util.CollectionUtils.isEmpty;
+
+
+@Component
 public class GroupOperation extends AbstractOperation implements IGroupOperation {
 
 
-	private static Logger log = LoggerFactory.getLogger(GroupOperation.class.getName());
+    private static final Logger log = Logger.getLogger(GroupOperation.class.getName());
+	private final TitanDao titanDao;
+	private final TopologyTemplateOperation topologyTemplateOperation;
+    private final PropertyOperation propertyOperation;
+    private final GroupTypeOperation groupTypeOperation;
+    private final ApplicationDataTypeCache dataTypeCache;
 
-	@javax.annotation.Resource
-	private PropertyOperation propertyOperation;
+    public GroupOperation(TitanDao titanDao, TopologyTemplateOperation topologyTemplateOperation, PropertyOperation propertyOperation, GroupTypeOperation groupTypeOperation, ApplicationDataTypeCache dataTypeCache) {
+        this.titanDao = titanDao;
+        this.topologyTemplateOperation = topologyTemplateOperation;
+        this.propertyOperation = propertyOperation;
+        this.groupTypeOperation = groupTypeOperation;
+        this.dataTypeCache = dataTypeCache;
+    }
 
-	@javax.annotation.Resource
-	private GroupTypeOperation groupTypeOperation;
-
-	@javax.annotation.Resource
-	private ApplicationDataTypeCache dataTypeCache;
-
-	private GroupDefinition convertGroupDataToGroupDefinition(GroupData groupData) {
-		GroupDefinition newGroupDefinition = new GroupDefinition(groupData.getGroupDataDefinition());
-		return newGroupDefinition;
-	}
-
-	/**
-	 * get members of group
-	 * 
-	 * @param groupUniqueId
-	 * @return
-	 */
-	private Either<Map<String, String>, TitanOperationStatus> getGroupMembers(String groupUniqueId) {
-
-		Either<Map<String, String>, TitanOperationStatus> result = null;
-
-		Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.GROUP_MEMBER,
-				NodeTypeEnum.ResourceInstance, ComponentInstanceData.class);
-
-		if (childrenNodes.isRight()) {
-			TitanOperationStatus status = childrenNodes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.OK;
-			}
-			result = Either.right(status);
-
-		} else {
-
-			Map<String, String> compInstaMap = new HashMap<>();
-			List<ImmutablePair<ComponentInstanceData, GraphEdge>> list = childrenNodes.left().value();
-			if (list != null) {
-				for (ImmutablePair<ComponentInstanceData, GraphEdge> pair : list) {
-					ComponentInstanceData componentInstanceData = pair.getKey();
-
-					String compInstUniqueId = componentInstanceData.getComponentInstDataDefinition().getUniqueId();
-					String compInstName = componentInstanceData.getName();
-					compInstaMap.put(compInstName, compInstUniqueId);
-				}
-			}
-
-			result = Either.left(compInstaMap);
-		}
-
-		return result;
-	}
-
-	private Either<GroupTypeDefinition, TitanOperationStatus> getGroupTypeOfGroup(String groupUniqueId) {
-
-		Either<ImmutablePair<GroupTypeData, GraphEdge>, TitanOperationStatus> groupTypeRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.TYPE_OF, NodeTypeEnum.GroupType,
-				GroupTypeData.class);
-
-		if (groupTypeRes.isRight()) {
-			TitanOperationStatus status = groupTypeRes.right().value();
-			log.debug("Cannot find group type associated with capability {}. Status is {}", groupUniqueId, status);
-
-			BeEcompErrorManager.getInstance().logBeFailedFindAssociationError("Fetch Group type", NodeTypeEnum.GroupType.getName(), groupUniqueId, String.valueOf(status));
-			return Either.right(groupTypeRes.right().value());
-		}
-
-		GroupTypeData groupTypeData = groupTypeRes.left().value().getKey();
-
-		return groupTypeOperation.getGroupTypeByUid(groupTypeData.getGroupTypeDataDefinition().getUniqueId());
+    private GroupDefinition convertGroupDataToGroupDefinition(GroupData groupData) {
+		return new GroupDefinition(groupData.getGroupDataDefinition());
 
 	}
 
-	/**
-	 * get all properties of the group.
-	 * 
-	 * the propert definition is taken from the group type.
-	 * 
-	 * @param groupUid
-	 * @return
-	 */
-	private Either<List<GroupProperty>, TitanOperationStatus> getGroupProperties(String groupUid) {
+    /**
+     * get members of group
+     *
+     * @param groupUniqueId
+     * @return
+     */
+    private Either<Map<String, String>, TitanOperationStatus> getGroupMembers(String groupUniqueId) {
 
-		List<GroupProperty> groupPropertiesList = new ArrayList<>();
+        Either<Map<String, String>, TitanOperationStatus> result = null;
 
-		Either<GroupTypeDefinition, TitanOperationStatus> groupTypeOfGroupRes = getGroupTypeOfGroup(groupUid);
+        Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.GROUP_MEMBER,
+                NodeTypeEnum.ResourceInstance, ComponentInstanceData.class);
 
-		if (groupTypeOfGroupRes.isRight()) {
-			TitanOperationStatus status = groupTypeOfGroupRes.right().value();
-			return Either.right(status);
-		}
+        if (childrenNodes.isRight()) {
+            TitanOperationStatus status = childrenNodes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.OK;
+            }
+            result = Either.right(status);
 
-		GroupTypeDefinition groupTypeDefinition = groupTypeOfGroupRes.left().value();
+        } else {
 
-		// Get the properties on the group type of this group
-		List<PropertyDefinition> groupTypeProperties = groupTypeDefinition.getProperties();
+            Map<String, String> compInstaMap = new HashMap<>();
+            List<ImmutablePair<ComponentInstanceData, GraphEdge>> list = childrenNodes.left().value();
+            if (list != null) {
+                for (ImmutablePair<ComponentInstanceData, GraphEdge> pair : list) {
+                    ComponentInstanceData componentInstanceData = pair.getKey();
 
-		if (groupTypeProperties == null || true == groupTypeProperties.isEmpty()) {
-			return Either.right(TitanOperationStatus.OK);
-		}
+                    String compInstUniqueId = componentInstanceData.getComponentInstDataDefinition().getUniqueId();
+                    String compInstName = componentInstanceData.getName();
+                    compInstaMap.put(compInstName, compInstUniqueId);
+                }
+            }
 
-		Map<String, PropertyDefinition> uidToPropDefMap = groupTypeProperties.stream().collect(Collectors.toMap(p -> p.getUniqueId(), p -> p));
+            result = Either.left(compInstaMap);
+        }
 
-		// Find all properties values on the group
-		Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUid, GraphEdgeLabels.PROPERTY_VALUE,
-				NodeTypeEnum.PropertyValue, PropertyValueData.class);
+        return result;
+    }
 
-		if (propertyImplNodes.isRight()) {
-			TitanOperationStatus status = propertyImplNodes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				groupPropertiesList = groupTypeProperties.stream().map(p -> new GroupProperty(p, p.getDefaultValue(), null)).collect(Collectors.toList());
-				return Either.left(groupPropertiesList);
-			} else {
-				return Either.right(status);
-			}
-		}
+    private Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeOfGroup(String groupUniqueId) {
 
-		List<ImmutablePair<PropertyValueData, GraphEdge>> list = propertyImplNodes.left().value();
-		if (list == null || true == list.isEmpty()) {
-			return Either.right(TitanOperationStatus.OK);
-		}
+        Either<ImmutablePair<GroupTypeData, GraphEdge>, StorageOperationStatus> groupTypeRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.TYPE_OF, NodeTypeEnum.GroupType,
+                GroupTypeData.class)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
 
-		List<String> processedProps = new ArrayList<>();
+        if (groupTypeRes.isRight()) {
+            StorageOperationStatus status = groupTypeRes.right().value();
+            log.debug("Cannot find group type associated with capability {}. Status is {}", groupUniqueId, status);
 
-		for (ImmutablePair<PropertyValueData, GraphEdge> propertyValue : list) {
+            BeEcompErrorManager.getInstance().logBeFailedFindAssociationError("Fetch Group type", NodeTypeEnum.GroupType.getName(), groupUniqueId, String.valueOf(status));
+            return Either.right(groupTypeRes.right().value());
+        }
 
-			PropertyValueData propertyValueData = propertyValue.getLeft();
-			String propertyValueUid = propertyValueData.getUniqueId();
-			String value = propertyValueData.getValue();
+        GroupTypeData groupTypeData = groupTypeRes.left().value().getKey();
 
-			Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, GraphEdgeLabels.PROPERTY_IMPL,
-					NodeTypeEnum.Property, PropertyData.class);
-			if (propertyDefRes.isRight()) {
-				TitanOperationStatus status = propertyDefRes.right().value();
-				if (status == TitanOperationStatus.NOT_FOUND) {
-					status = TitanOperationStatus.INVALID_ID;
-				}
-				return Either.right(status);
-			}
+        return groupTypeOperation.getGroupTypeByUid(groupTypeData.getGroupTypeDataDefinition().getUniqueId());
 
-			ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value();
+    }
 
-			PropertyData propertyData = propertyDefPair.left;
-			String propertyUniqueId = propertyData.getPropertyDataDefinition().getUniqueId();
+    /**
+     * get all properties of the group.
+     *
+     * the propert definition is taken from the group type.
+     *
+     * @param groupUid
+     * @return
+     */
+    private Either<List<GroupProperty>, StorageOperationStatus> getGroupProperties(String groupUid) {
 
-			PropertyDefinition propertyDefinition = uidToPropDefMap.get(propertyUniqueId);
-			GroupProperty groupProperty = new GroupProperty(propertyDefinition, value, propertyValueUid);
+        List<GroupProperty> groupPropertiesList = new ArrayList<>();
 
-			processedProps.add(propertyUniqueId);
+        Either<GroupTypeDefinition, StorageOperationStatus> groupTypeOfGroupRes = getGroupTypeOfGroup(groupUid);
 
-			groupPropertiesList.add(groupProperty);
+        if (groupTypeOfGroupRes.isRight()) {
+            StorageOperationStatus status = groupTypeOfGroupRes.right().value();
+            return Either.right(status);
+        }
 
-		}
+        GroupTypeDefinition groupTypeDefinition = groupTypeOfGroupRes.left().value();
 
-		// Find all properties which does not have property value on the group.
-		List<GroupProperty> leftProps = groupTypeProperties.stream()
-				// filter out the group type properties which already processed
-				.filter(p -> false == processedProps.contains(p.getUniqueId())).map(p -> new GroupProperty(p, p.getDefaultValue(), null)).collect(Collectors.toList());
-		if (leftProps != null) {
-			groupPropertiesList.addAll(leftProps);
-		}
+        // Get the properties on the group type of this group
+        List<PropertyDefinition> groupTypeProperties = groupTypeDefinition.getProperties();
 
-		return Either.left(groupPropertiesList);
-	}
+        if (isEmpty(groupTypeProperties)) {
+            return Either.right(StorageOperationStatus.OK);
+        }
 
-	@Override
-	public Either<List<GraphRelation>, TitanOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, String artifactId) {
+        Map<String, PropertyDefinition> uidToPropDefMap = groupTypeProperties.stream().collect(Collectors.toMap(PropertyDefinition::getUniqueId, Function.identity()));
 
-		List<GraphRelation> relations = new ArrayList<>();
-		Either<List<GraphRelation>, TitanOperationStatus> result = Either.left(relations);
+        // Find all properties values on the group
+        Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, StorageOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUid, GraphEdgeLabels.PROPERTY_VALUE,
+                NodeTypeEnum.PropertyValue, PropertyValueData.class)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
 
-		Either<List<GroupDefinition>, TitanOperationStatus> allGroupsFromGraph = getAllGroupsFromGraph(componentId, componentTypeEnum, true, true, false);
-		if (allGroupsFromGraph.isRight()) {
-			TitanOperationStatus status = allGroupsFromGraph.right().value();
-			return Either.right(status);
-		}
+        if (propertyImplNodes.isRight()) {
+            StorageOperationStatus status = propertyImplNodes.right().value();
+            if (status == StorageOperationStatus.NOT_FOUND) {
+                groupPropertiesList = groupTypeProperties.stream().map(p -> new GroupProperty(p, p.getDefaultValue(), null)).collect(Collectors.toList());
+                return Either.left(groupPropertiesList);
+            } else {
+                return Either.right(status);
+            }
+        }
 
-		List<GroupDefinition> allGroups = allGroupsFromGraph.left().value();
-		if (allGroups == null || allGroups.isEmpty()) {
-			return Either.right(TitanOperationStatus.OK);
-		}
+        List<ImmutablePair<PropertyValueData, GraphEdge>> list = propertyImplNodes.left().value();
+        if (isEmpty(list)) {
+            return Either.right(StorageOperationStatus.OK);
+        }
 
-		// Find all groups which contains this artifact id
-		List<GroupDefinition> associatedGroups = allGroups.stream().filter(p -> p.getArtifacts() != null && p.getArtifacts().contains(artifactId)).collect(Collectors.toList());
+        List<String> processedProps = new ArrayList<>();
 
-		if (associatedGroups != null && false == associatedGroups.isEmpty()) {
-			log.debug("The groups {} contains the artifact {}", associatedGroups.stream().map(p -> p.getName()).collect(Collectors.toList()), artifactId);
+        for (ImmutablePair<PropertyValueData, GraphEdge> propertyValue : list) {
 
-			UniqueIdData artifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId);
-			for (GroupDefinition groupDefinition : associatedGroups) {
-				UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupDefinition.getUniqueId());
-				Either<GraphRelation, TitanOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, artifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF);
-				if (deleteRelation.isRight()) {
-					TitanOperationStatus status = deleteRelation.right().value();
-					if (status == TitanOperationStatus.NOT_FOUND) {
-						status = TitanOperationStatus.INVALID_ID;
-					}
-					return Either.right(status);
-				}
+            PropertyValueData propertyValueData = propertyValue.getLeft();
+            String propertyValueUid = propertyValueData.getUniqueId();
+            String value = propertyValueData.getValue();
 
-				relations.add(deleteRelation.left().value());
-			}
+            Either<ImmutablePair<PropertyData, GraphEdge>, StorageOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, GraphEdgeLabels.PROPERTY_IMPL,
+                    NodeTypeEnum.Property, PropertyData.class)
+                    .right()
+                    .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+            if (propertyDefRes.isRight()) {
+                StorageOperationStatus status = propertyDefRes.right().value();
+                if (status == StorageOperationStatus.NOT_FOUND) {
+                    status = StorageOperationStatus.INVALID_ID;
+                }
+                return Either.right(status);
+            }
 
-			return result;
+            ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value();
 
-		} else {
-			log.debug("No group under component id {} is associated to artifact {}", componentId, artifactId);
-			return Either.right(TitanOperationStatus.OK);
-		}
+            PropertyData propertyData = propertyDefPair.left;
+            String propertyUniqueId = propertyData.getPropertyDataDefinition().getUniqueId();
 
-	}
+            PropertyDefinition propertyDefinition = uidToPropDefMap.get(propertyUniqueId);
+            GroupProperty groupProperty = new GroupProperty(propertyDefinition, value, propertyValueUid);
 
-	public Either<GroupDefinition, TitanOperationStatus> getGroupFromGraph(String uniqueId, boolean skipProperties, boolean skipMembers, boolean skipArtifacts) {
+            processedProps.add(propertyUniqueId);
 
-		Either<GroupDefinition, TitanOperationStatus> result = null;
+            groupPropertiesList.add(groupProperty);
 
-		Either<GroupData, TitanOperationStatus> groupRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), uniqueId, GroupData.class);
-		if (groupRes.isRight()) {
-			TitanOperationStatus status = groupRes.right().value();
-			log.debug("Failed to retrieve group {}  from graph. Status is {}", uniqueId, status);
-			BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Group", uniqueId, String.valueOf(status));
-			result = Either.right(status);
-			return result;
-		}
+        }
 
-		GroupData groupData = groupRes.left().value();
+        // Find all properties which does not have property value on the group.
+        List<GroupProperty> leftProps = groupTypeProperties.stream()
+                // filter out the group type properties which already processed
+                .filter(p -> !processedProps.contains(p.getUniqueId()))
+                .map(p -> new GroupProperty(p, p.getDefaultValue(), null))
+                .collect(Collectors.toList());
+        if (leftProps != null) {
+            groupPropertiesList.addAll(leftProps);
+        }
 
-		GroupDefinition groupDefinition = convertGroupDataToGroupDefinition(groupData);
+        return Either.left(groupPropertiesList);
+    }
 
-		Either<GroupTypeDefinition, TitanOperationStatus> groupTypeOfGroup = getGroupTypeOfGroup(uniqueId);
+    @Override
+    public Either<List<GraphRelation>, StorageOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, String artifactId) {
 
-		if (groupTypeOfGroup.isRight()) {
-			TitanOperationStatus status = groupTypeOfGroup.right().value();
-			log.debug("Failed to retrieve capability type of capability {}. Status is {}", uniqueId, status);
+        List<GraphRelation> relations = new ArrayList<>();
+        Either<List<GraphRelation>, StorageOperationStatus> result = Either.left(relations);
 
-			result = Either.right(status);
-			return result;
-		}
+        Either<List<GroupDefinition>, StorageOperationStatus> allGroupsFromGraph = getAllGroupsFromGraph(componentId, componentTypeEnum, true, true, false);
+        if (allGroupsFromGraph.isRight()) {
+            StorageOperationStatus status = allGroupsFromGraph.right().value();
+            return Either.right(status);
+        }
 
-		GroupTypeDefinition groupTypeDefinition = groupTypeOfGroup.left().value();
+        List<GroupDefinition> allGroups = allGroupsFromGraph.left().value();
+        if (isEmpty(allGroups)) {
+            return Either.right(StorageOperationStatus.OK);
+        }
 
-		groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId());
+        // Find all groups which contains this artifact id
+        List<GroupDefinition> associatedGroups = allGroups.stream().filter(p -> p.getArtifacts() != null && p.getArtifacts().contains(artifactId)).collect(Collectors.toList());
 
-		if (false == skipMembers) {
-			Either<Map<String, String>, TitanOperationStatus> membersRes = getGroupMembers(uniqueId);
-			if (membersRes.isRight()) {
-				TitanOperationStatus status = membersRes.right().value();
-				if (status != TitanOperationStatus.OK) {
-					result = Either.right(status);
-					return result;
-				}
-			} else {
-				Map<String, String> members = membersRes.left().value();
-				groupDefinition.setMembers(members);
-			}
-		}
+        if (isNotEmpty(associatedGroups)) {
+            log.debug("The groups {} contains the artifact {}", associatedGroups.stream().map(GroupDataDefinition::getName).collect(Collectors.toList()), artifactId);
 
-		if (false == skipProperties) {
-			Either<List<GroupProperty>, TitanOperationStatus> propertiesRes = getGroupProperties(uniqueId);
-			if (propertiesRes.isRight()) {
-				TitanOperationStatus status = propertiesRes.right().value();
-				if (status != TitanOperationStatus.OK) {
-					result = Either.right(status);
-					return result;
-				}
-			} else {
-				List<GroupProperty> properties = propertiesRes.left().value();
-				groupDefinition.convertFromGroupProperties(properties);
-			}
-		}
+            UniqueIdData artifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId);
+            for (GroupDefinition groupDefinition : associatedGroups) {
+                UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupDefinition.getUniqueId());
+                Either<GraphRelation, StorageOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, artifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF)
+                        .right()
+                        .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+                if (deleteRelation.isRight()) {
+                    StorageOperationStatus status = deleteRelation.right().value();
+                    if (status == StorageOperationStatus.NOT_FOUND) {
+                        status = StorageOperationStatus.INVALID_ID;
+                    }
+                    return Either.right(status);
+                }
 
-		if (false == skipArtifacts) {
-			Either<List<ImmutablePair<String, String>>, TitanOperationStatus> artifactsRes = getGroupArtifactsPairs(uniqueId);
-			if (artifactsRes.isRight()) {
-				TitanOperationStatus status = artifactsRes.right().value();
-				if (status != TitanOperationStatus.OK) {
-					result = Either.right(status);
-					return result;
-				}
-			} else {
-				List<String> artifactsUid = new ArrayList<>();
-				List<String> artifactsUUID = new ArrayList<>();
+                relations.add(deleteRelation.left().value());
+            }
 
-				List<ImmutablePair<String, String>> list = artifactsRes.left().value();
-				if (list != null) {
-					for (ImmutablePair<String, String> pair : list) {
-						String uid = pair.left;
-						String UUID = pair.right;
-						artifactsUid.add(uid);
-						artifactsUUID.add(UUID);
-					}
-					groupDefinition.setArtifacts(artifactsUid);
-					groupDefinition.setArtifactsUuid(artifactsUUID);
-				}
-			}
-		}
-		result = Either.left(groupDefinition);
+            return result;
 
-		return result;
+        } else {
+            log.debug("No group under component id {} is associated to artifact {}", componentId, artifactId);
+            return Either.right(StorageOperationStatus.OK);
+        }
 
-	}
+    }
 
-	@Override
-	public boolean isGroupExist(String groupName, boolean inTransaction) {
+    public Either<GroupDefinition, StorageOperationStatus> getGroupFromGraph(String uniqueId, boolean skipProperties, boolean skipMembers, boolean skipArtifacts) {
 
-		Either<List<GroupData>, TitanOperationStatus> eitherGroup = null;
-		try {
-			Map<String, Object> properties = new HashMap<>();
-			properties.put(GraphPropertiesDictionary.NAME.getProperty(), groupName);
+        Either<GroupDefinition, StorageOperationStatus> result = null;
 
-			eitherGroup = titanGenericDao.getByCriteria(NodeTypeEnum.Group, properties, GroupData.class);
-			return eitherGroup.isLeft() && !eitherGroup.left().value().isEmpty();
+        Either<GroupData, StorageOperationStatus> groupRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), uniqueId, GroupData.class)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+        if (groupRes.isRight()) {
+            StorageOperationStatus status = groupRes.right().value();
+            log.debug("Failed to retrieve group {}  from graph. Status is {}", uniqueId, status);
+            BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Group", uniqueId, String.valueOf(status));
+            result = Either.right(status);
+            return result;
+        }
 
-		} finally {
-			handleTransactionCommitRollback(inTransaction, eitherGroup);
-		}
-	}
+        GroupData groupData = groupRes.left().value();
 
-	protected Either<List<GroupDefinition>, TitanOperationStatus> getAllGroupsFromGraph(String componentId, NodeTypeEnum componentTypeEnum, boolean skipProperties, boolean skipMembers, boolean skipArtifacts) {
+        GroupDefinition groupDefinition = convertGroupDataToGroupDefinition(groupData);
 
-		List<GroupDefinition> groups = new ArrayList<GroupDefinition>();
+        Either<GroupTypeDefinition, StorageOperationStatus> groupTypeOfGroup = getGroupTypeOfGroup(uniqueId);
 
-		Either<List<ImmutablePair<GroupData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(componentTypeEnum), componentId, GraphEdgeLabels.GROUP, NodeTypeEnum.Group,
-				GroupData.class);
+        if (groupTypeOfGroup.isRight()) {
+            StorageOperationStatus status = groupTypeOfGroup.right().value();
+            log.debug("Failed to retrieve capability type of capability {}. Status is {}", uniqueId, status);
 
-		if (childrenNodes.isRight()) {
-			TitanOperationStatus status = childrenNodes.right().value();
-			return Either.right(status);
-		}
+            result = Either.right(status);
+            return result;
+        }
 
-		List<ImmutablePair<GroupData, GraphEdge>> graphGroups = childrenNodes.left().value();
+        GroupTypeDefinition groupTypeDefinition = groupTypeOfGroup.left().value();
 
-		if (graphGroups == null || true == graphGroups.isEmpty()) {
-			return Either.right(TitanOperationStatus.NOT_FOUND);
-		}
+        groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId());
 
-		// Consumer<String> consumer = (x) -> getGroup(x);
-		// StreamUtils.takeWhile(graphGroups.stream().map(p ->
-		// p.left.getUniqueId()), consumer);
+        if (!skipMembers) {
+            Either<Map<String, String>, StorageOperationStatus> membersRes = getGroupMembers(uniqueId)
+                    .right()
+                    .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+            if (membersRes.isRight()) {
+                StorageOperationStatus status = membersRes.right().value();
+                if (status != StorageOperationStatus.OK) {
+                    result = Either.right(status);
+                    return result;
+                }
+            } else {
+                Map<String, String> members = membersRes.left().value();
+                groupDefinition.setMembers(members);
+            }
+        }
+
+        if (!skipProperties) {
+            Either<List<GroupProperty>, StorageOperationStatus> propertiesRes = getGroupProperties(uniqueId);
+            if (propertiesRes.isRight()) {
+                StorageOperationStatus status = propertiesRes.right().value();
+                if (status != StorageOperationStatus.OK) {
+                    result = Either.right(status);
+                    return result;
+                }
+            } else {
+                List<GroupProperty> properties = propertiesRes.left().value();
+                groupDefinition.convertFromGroupProperties(properties);
+            }
+        }
+
+        if (!skipArtifacts) {
+            Either<List<ImmutablePair<String, String>>, StorageOperationStatus> artifactsRes = getGroupArtifactsPairs(uniqueId)
+                    .right()
+                    .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+            if (artifactsRes.isRight()) {
+                StorageOperationStatus status = artifactsRes.right().value();
+                if (status != StorageOperationStatus.OK) {
+                    result = Either.right(status);
+                    return result;
+                }
+            } else {
+                List<String> artifactsUid = new ArrayList<>();
+                List<String> artifactsUUID = new ArrayList<>();
+
+                List<ImmutablePair<String, String>> list = artifactsRes.left().value();
+                if (list != null) {
+                    for (ImmutablePair<String, String> pair : list) {
+                        String uid = pair.left;
+                        String UUID = pair.right;
+                        artifactsUid.add(uid);
+                        artifactsUUID.add(UUID);
+                    }
+                    groupDefinition.setArtifacts(artifactsUid);
+                    groupDefinition.setArtifactsUuid(artifactsUUID);
+                }
+            }
+        }
+        result = Either.left(groupDefinition);
+
+        return result;
+
+    }
+
+    @Override
+    public boolean isGroupExist(String groupName, boolean inTransaction) {
+
+        Either<List<GroupData>, TitanOperationStatus> eitherGroup = null;
+        try {
+            Map<String, Object> properties = new HashMap<>();
+            properties.put(GraphPropertiesDictionary.NAME.getProperty(), groupName);
+
+            eitherGroup = titanGenericDao.getByCriteria(NodeTypeEnum.Group, properties, GroupData.class);
+            return eitherGroup.isLeft() && !eitherGroup.left().value().isEmpty();
+
+        } finally {
+            handleTransactionCommitRollback(inTransaction, eitherGroup);
+        }
+    }
+
+    protected Either<List<GroupDefinition>, StorageOperationStatus> getAllGroupsFromGraph(String componentId, NodeTypeEnum componentTypeEnum, boolean skipProperties, boolean skipMembers, boolean skipArtifacts) {
+
+        List<GroupDefinition> groups = new ArrayList<>();
+
+        Either<List<ImmutablePair<GroupData, GraphEdge>>, StorageOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(componentTypeEnum), componentId, GraphEdgeLabels.GROUP, NodeTypeEnum.Group,
+                GroupData.class)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+
+        if (childrenNodes.isRight()) {
+            StorageOperationStatus status = childrenNodes.right().value();
+            return Either.right(status);
+        }
+
+        List<ImmutablePair<GroupData, GraphEdge>> graphGroups = childrenNodes.left().value();
+
+        if (isEmpty(graphGroups)) {
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+
+
 
 		for (ImmutablePair<GroupData, GraphEdge> pair : graphGroups) {
 
-			String groupUniqueId = pair.left.getGroupDataDefinition().getUniqueId();
-			Either<GroupDefinition, TitanOperationStatus> groupRes = this.getGroupFromGraph(groupUniqueId, skipProperties, skipMembers, skipArtifacts);
+            String groupUniqueId = pair.left.getGroupDataDefinition().getUniqueId();
+            Either<GroupDefinition, StorageOperationStatus> groupRes = this.getGroupFromGraph(groupUniqueId, skipProperties, skipMembers, skipArtifacts);
 
-			if (groupRes.isRight()) {
-				TitanOperationStatus status = groupRes.right().value();
-				if (status == TitanOperationStatus.NOT_FOUND) {
-					status = TitanOperationStatus.INVALID_ID;
-				}
-				return Either.right(status);
-			} else {
-				groups.add(groupRes.left().value());
-			}
+            if (groupRes.isRight()) {
+                StorageOperationStatus status = groupRes.right().value();
+                if (status == StorageOperationStatus.NOT_FOUND) {
+                    status = StorageOperationStatus.INVALID_ID;
+                }
+                return Either.right(status);
+            } else {
+                groups.add(groupRes.left().value());
+            }
 
-		}
+        }
 
-		return Either.left(groups);
-	}
+        return Either.left(groups);
+    }
 
-	private TitanOperationStatus dissociateAndAssociateGroupsFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) {
+    private StorageOperationStatus dissociateAndAssociateGroupsFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) {
 
-		Either<List<GroupDefinition>, TitanOperationStatus> allGroupsFromGraph = getAllGroupsFromGraph(componentId, componentTypeEnum, true, true, false);
+		Either<List<GroupDefinition>, StorageOperationStatus> allGroupsFromGraph = getAllGroupsFromGraph(componentId, componentTypeEnum, true, true, false);
 		if (allGroupsFromGraph.isRight()) {
-			TitanOperationStatus status = allGroupsFromGraph.right().value();
-			return status;
-		}
-
-		List<GroupDefinition> allGroups = allGroupsFromGraph.left().value();
-		if (allGroups == null || allGroups.isEmpty()) {
-			return TitanOperationStatus.OK;
-		}
-
-		// Find all groups which contains this artifact id
-		List<GroupDefinition> associatedGroups = allGroups.stream().filter(p -> p.getArtifacts() != null && p.getArtifacts().contains(oldArtifactId)).collect(Collectors.toList());
-
-		if (associatedGroups != null && false == associatedGroups.isEmpty()) {
-
-			log.debug("The groups {} contains the artifact {}", associatedGroups.stream().map(p -> p.getName()).collect(Collectors.toList()), oldArtifactId);
-
-			UniqueIdData oldArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, oldArtifactId);
-			UniqueIdData newArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, newArtifact.getArtifactDataDefinition().getUniqueId());
-			Map<String, Object> props = new HashMap<String, Object>();
-			props.put(GraphPropertiesDictionary.NAME.getProperty(), newArtifactData.getLabel());
-
-			for (GroupDefinition groupDefinition : associatedGroups) {
-				UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupDefinition.getUniqueId());
-
-				Either<GraphRelation, TitanOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, oldArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF);
-				log.trace("After dissociate group {} from artifact {}"  , groupDefinition.getName(), oldArtifactId);
-				if (deleteRelation.isRight()) {
-					TitanOperationStatus status = deleteRelation.right().value();
-					if (status == TitanOperationStatus.NOT_FOUND) {
-						status = TitanOperationStatus.INVALID_ID;
-					}
-					return status;
-				}
-
-				Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(groupData, newArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF, props);
-				log.trace("After associate group {} to artifact {}" , groupDefinition.getName(), newArtifact.getUniqueIdKey());
-				if (createRelation.isRight()) {
-					TitanOperationStatus status = createRelation.right().value();
-					if (status == TitanOperationStatus.NOT_FOUND) {
-						status = TitanOperationStatus.INVALID_ID;
-					}
-					return status;
-				}
-			}
+			return allGroupsFromGraph.right().value();
 
 		}
-		return TitanOperationStatus.OK;
-	}
 
-	@Override
-	public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact, boolean inTransaction) {
+        List<GroupDefinition> allGroups = allGroupsFromGraph.left().value();
+        if (isEmpty(allGroups)) {
+            return StorageOperationStatus.OK;
+        }
 
-		StorageOperationStatus result = null;
+        // Find all groups which contains this artifact id
+        List<GroupDefinition> associatedGroups = allGroups.stream().filter(p -> p.getArtifacts() != null && p.getArtifacts().contains(oldArtifactId)).collect(Collectors.toList());
 
-		try {
-			TitanOperationStatus status = this.dissociateAndAssociateGroupsFromArtifactOnGraph(componentId, componentTypeEnum, oldArtifactId, newArtifact);
+        if (isNotEmpty(associatedGroups)) {
 
-			if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
-				result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-				return result;
-			}
+            log.debug("The groups {} contains the artifact {}", associatedGroups.stream().map(GroupDataDefinition::getName).collect(Collectors.toList()), oldArtifactId);
 
-			result = StorageOperationStatus.OK;
-			return result;
+            UniqueIdData oldArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, oldArtifactId);
+            UniqueIdData newArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, newArtifact.getArtifactDataDefinition().getUniqueId());
+            Map<String, Object> props = new HashMap<>();
+            props.put(GraphPropertiesDictionary.NAME.getProperty(), newArtifactData.getLabel());
 
-		} finally {
-			if (false == inTransaction) {
-				if (result == null || result != StorageOperationStatus.OK) {
-					log.debug("Going to execute rollback on graph.");
-					BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph");
-					titanGenericDao.rollback();
-				} else {
-					log.debug("Going to execute commit on graph.");
-					titanGenericDao.commit();
-				}
-			}
-		}
-	}
+            for (GroupDefinition groupDefinition : associatedGroups) {
+                UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupDefinition.getUniqueId());
 
-	private Either<List<ImmutablePair<String, String>>, TitanOperationStatus> getGroupArtifactsPairs(String groupUniqueId) {
+                Either<GraphRelation, StorageOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, oldArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF)
+                        .right()
+                        .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+                log.trace("After dissociate group {} from artifact {}"  , groupDefinition.getName(), oldArtifactId);
+                if (deleteRelation.isRight()) {
+                    StorageOperationStatus status = deleteRelation.right().value();
+                    if (status == StorageOperationStatus.NOT_FOUND) {
+                        status = StorageOperationStatus.INVALID_ID;
+                    }
+                    return status;
+                }
 
-		Either<List<ImmutablePair<String, String>>, TitanOperationStatus> result = null;
+                Either<GraphRelation, StorageOperationStatus> createRelation = titanGenericDao.createRelation(groupData, newArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF, props)
+                        .right()
+                        .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+                log.trace("After associate group {} to artifact {}" , groupDefinition.getName(), newArtifact.getUniqueIdKey());
+                if (createRelation.isRight()) {
+                    StorageOperationStatus status = createRelation.right().value();
+                    if (status == StorageOperationStatus.NOT_FOUND) {
+                        status = StorageOperationStatus.INVALID_ID;
+                    }
+                    return status;
+                }
+            }
 
-		Either<List<ImmutablePair<ArtifactData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.GROUP_ARTIFACT_REF,
-				NodeTypeEnum.ArtifactRef, ArtifactData.class);
-		if (childrenNodes.isRight()) {
-			TitanOperationStatus status = childrenNodes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.OK;
-			}
-			result = Either.right(status);
+        }
+        return StorageOperationStatus.OK;
+    }
 
+    @Override
+    public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact, boolean inTransaction) {
+
+        StorageOperationStatus result = null;
+
+        try {
+            StorageOperationStatus status = this.dissociateAndAssociateGroupsFromArtifactOnGraph(componentId, componentTypeEnum, oldArtifactId, newArtifact);
+
+            if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
+                return status;
+            }
+
+            result = StorageOperationStatus.OK;
+            return result;
+
+        } finally {
+            if (!inTransaction) {
+                if (result == null || result != StorageOperationStatus.OK) {
+                    log.debug("Going to execute rollback on graph.");
+                    BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph");
+                    titanGenericDao.rollback();
+                } else {
+                    log.debug("Going to execute commit on graph.");
+                    titanGenericDao.commit();
+                }
+            }
+        }
+    }
+
+    private Either<List<ImmutablePair<String, String>>, TitanOperationStatus> getGroupArtifactsPairs(String groupUniqueId) {
+
+        Either<List<ImmutablePair<String, String>>, TitanOperationStatus> result = null;
+
+        Either<List<ImmutablePair<ArtifactData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.GROUP_ARTIFACT_REF,
+                NodeTypeEnum.ArtifactRef, ArtifactData.class);
+        if (childrenNodes.isRight()) {
+            TitanOperationStatus status = childrenNodes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.OK;
+            }
+            result = Either.right(status);
+
+        } else {
+
+            List<ImmutablePair<String, String>> artifactsList = new ArrayList<>();
+            List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenNodes.left().value();
+            if (list != null) {
+                for (ImmutablePair<ArtifactData, GraphEdge> pair : list) {
+                    ArtifactData artifactData = pair.getKey();
+                    String uniqueId = artifactData.getArtifactDataDefinition().getUniqueId();
+                    String UUID = artifactData.getArtifactDataDefinition().getArtifactUUID();
+                    ImmutablePair<String, String> artifact = new ImmutablePair<>(uniqueId, UUID);
+                    artifactsList.add(artifact);
+                }
+            }
+
+            log.debug("The artifacts list related to group {} is {}", groupUniqueId, artifactsList);
+            result = Either.left(artifactsList);
+        }
+
+        return result;
+
+    }
+
+    @Override
+    public StorageOperationStatus validateAndUpdatePropertyValue(GroupProperty property) {
+
+        StorageOperationStatus result = null;
+        String innerType = property.getSchema() == null ? null : property.getSchema().getProperty() == null ? null : property.getSchema().getProperty().getType();
+        Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
+        Either<Object, Boolean> isValid = null;
+        if (allDataTypes.isRight()) {
+            TitanOperationStatus status = allDataTypes.right().value();
+            log.debug("Failed to fetch data types from cache. Status is {}. ", status);
+            result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
+        if(result == null){
+            isValid = propertyOperation.validateAndUpdatePropertyValue(property.getType(), property.getValue(), innerType, allDataTypes.left().value());
+            if(isValid.isRight()){
+                log.debug("Failed to validate property value {}. Status is {}. ", property.getValue(), StorageOperationStatus.INVALID_PROPERTY);
+                result =  StorageOperationStatus.INVALID_PROPERTY;
+            }
+        }
+        if(result == null){
+            String validValue = String.valueOf(isValid.left().value());
+            property.setValue(validValue);
+            result = StorageOperationStatus.OK;
+        }
+        return result;
+    }
+
+	public StorageOperationStatus updateGroupProperties(org.openecomp.sdc.be.model.Component containerComponent, String groupId, List<PropertyDataDefinition> propertiesToUpdate) {
+		log.debug("#updateGroupProperties - updating the properties of group {} in component {}", groupId, containerComponent.getUniqueId());
+		Optional<GroupDefinition> group = containerComponent.getGroupById(groupId);
+		if (group.isPresent()){
+			return titanDao.getVertexById(containerComponent.getUniqueId(), JsonParseFlagEnum.NoParse)
+					.either(containerVertex -> updateGroupProperties(containerVertex, group.get(), propertiesToUpdate),
+							DaoStatusConverter::convertTitanStatusToStorageStatus);
 		} else {
-
-			List<ImmutablePair<String, String>> artifactsList = new ArrayList<>();
-			List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenNodes.left().value();
-			if (list != null) {
-				for (ImmutablePair<ArtifactData, GraphEdge> pair : list) {
-					ArtifactData artifactData = pair.getKey();
-					String uniqueId = artifactData.getArtifactDataDefinition().getUniqueId();
-					String UUID = artifactData.getArtifactDataDefinition().getArtifactUUID();
-					ImmutablePair<String, String> artifact = new ImmutablePair<String, String>(uniqueId, UUID);
-					artifactsList.add(artifact);
-				}
-			}
-
-			log.debug("The artifacts list related to group {} is {}", groupUniqueId, artifactsList);
-			result = Either.left(artifactsList);
+			throw new StorageException(StorageOperationStatus.NOT_FOUND, groupId);
 		}
-
-		return result;
-
 	}
 
-	@Override
-	public StorageOperationStatus validateAndUpdatePropertyValue(GroupProperty property) {
-		
-		StorageOperationStatus result = null;
-		String innerType = property.getSchema() == null ? null : property.getSchema().getProperty() == null ? null : property.getSchema().getProperty().getType();
-		Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
-		Either<Object, Boolean> isValid = null;
-		if (allDataTypes.isRight()) {
-			TitanOperationStatus status = allDataTypes.right().value();
-			log.debug("Failed to fetch data types from cache. Status is {}. ", status);
-			result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
-		if(result == null){
-			isValid = propertyOperation.validateAndUpdatePropertyValue(property.getType(), property.getValue(), innerType, allDataTypes.left().value());
-			if(isValid.isRight()){
-				log.debug("Failed to validate property value {}. Status is {}. ", property.getValue(), StorageOperationStatus.INVALID_PROPERTY);
-				result =  StorageOperationStatus.INVALID_PROPERTY;
-			}
-		}
-		if(result == null){
-			String validValue = String.valueOf(isValid.left().value());
-			property.setValue(validValue);
-			result = StorageOperationStatus.OK;
-		}
-		return result;
+	private StorageOperationStatus updateGroupProperties(GraphVertex container, GroupDefinition group, List<PropertyDataDefinition> propertiesToUpdate) {
+		List<PropertyDataDefinition> groupProperties = group.getProperties();
+		List<PropertyDataDefinition> updatedGroupProperties = updateGroupProperties(groupProperties, propertiesToUpdate);
+		group.setProperties(updatedGroupProperties);
+		return topologyTemplateOperation.updateGroupOfToscaElement(container, group);
 	}
+
+	private List<PropertyDataDefinition> updateGroupProperties(List<PropertyDataDefinition> currentGroupProperties, List<PropertyDataDefinition> toBeUpdatedProperties) {
+		Map<String, PropertyDataDefinition> currPropsByName = MapUtil.toMap(currentGroupProperties, PropertyDataDefinition::getName);
+		overrideCurrentPropertiesWithUpdatedProperties(currPropsByName, toBeUpdatedProperties);
+		return new ArrayList<>(currPropsByName.values());
+	}
+
+	private void overrideCurrentPropertiesWithUpdatedProperties(Map<String, PropertyDataDefinition> currPropsByName, List<PropertyDataDefinition> toBeUpdatedProperties) {
+		toBeUpdatedProperties.forEach(prop -> currPropsByName.put(prop.getName(), prop));
+	}
+
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java
index b17bab3..1817868 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java
@@ -20,83 +20,78 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import static org.openecomp.sdc.be.dao.titan.TitanUtils.buildNotInPredicate;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import javax.annotation.Resource;
-
+import com.google.common.base.Strings;
+import com.thinkaurelius.titan.graphdb.query.TitanPredicate;
+import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
+import org.openecomp.sdc.be.dao.neo4j.GraphEdgePropertiesDictionary;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.elements.GroupTypeDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
 import org.openecomp.sdc.be.model.GroupTypeDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.operations.StorageException;
+import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
-import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
-import org.openecomp.sdc.be.resources.data.GroupTypeData;
-import org.openecomp.sdc.be.resources.data.PropertyData;
-import org.openecomp.sdc.be.resources.data.UniqueIdData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Qualifier;
+import org.openecomp.sdc.be.model.operations.api.TypeOperations;
+import org.openecomp.sdc.be.model.utils.TypeCompareUtils;
+import org.openecomp.sdc.be.resources.data.*;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
-import com.google.common.base.Strings;
-import com.thinkaurelius.titan.graphdb.query.TitanPredicate;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
-import fj.data.Either;
+import static org.openecomp.sdc.be.dao.titan.TitanUtils.buildNotInPredicate;
 
 @Component("group-type-operation")
-public class GroupTypeOperation extends AbstractOperation implements IGroupTypeOperation {
-    @Resource
-    private CapabilityTypeOperation capabilityTypeOperation;
+public class GroupTypeOperation implements IGroupTypeOperation {
 
-    private static final Logger log = LoggerFactory.getLogger(GroupTypeOperation.class);
-
+    private static final Logger log = Logger.getLogger(GroupTypeOperation.class.getName());
     private static final String CREATE_FLOW_CONTEXT = "CreateGroupType";
-    private static final String GET_FLOW_CONTEXT = "GetGroupType";
 
-    private PropertyOperation propertyOperation;
+    private final PropertyOperation propertyOperation;
+    private final TitanGenericDao titanGenericDao;
+    private final CapabilityTypeOperation capabilityTypeOperation;
+    private final CapabilityOperation capabilityOperation;
+    private final DerivedFromOperation derivedFromOperation;
+    private final OperationUtils operationUtils;
 
-    private TitanGenericDao titanGenericDao;
 
-    public GroupTypeOperation(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao, @Qualifier("property-operation") PropertyOperation propertyOperation) {
-        super();
+    public GroupTypeOperation(TitanGenericDao titanGenericDao,
+                              PropertyOperation propertyOperation,
+                              CapabilityTypeOperation capabilityTypeOperation,
+                              CapabilityOperation capabilityOperation,
+                              DerivedFromOperation derivedFromOperation, OperationUtils operationUtils) {
+        this.titanGenericDao = titanGenericDao;
         this.propertyOperation = propertyOperation;
-        this.titanGenericDao = titanGenericDao;
-    }
-
-    /**
-     * FOR TEST ONLY
-     *
-     * @param titanGenericDao
-     */
-    public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
-        this.titanGenericDao = titanGenericDao;
+        this.capabilityTypeOperation = capabilityTypeOperation;
+        this.capabilityOperation = capabilityOperation;
+        this.derivedFromOperation = derivedFromOperation;
+        this.operationUtils = operationUtils;
     }
 
     @Override
     public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition) {
-
-        return addGroupType(groupTypeDefinition, false);
+        Either<GroupTypeDefinition, StorageOperationStatus> validationRes = validateUpdateProperties(groupTypeDefinition);
+        if (validationRes.isRight()) {
+            log.error("#addGroupType - One or all properties of group type {} not valid. status is {}", groupTypeDefinition, validationRes.right().value());
+            return validationRes;
+        }
+        
+        return addGroupType(groupTypeDefinition, true);
     }
 
     @Override
@@ -111,84 +106,206 @@
             if (eitherStatus.isRight()) {
                 BeEcompErrorManager.getInstance().logBeFailedCreateNodeError(CREATE_FLOW_CONTEXT, groupTypeDefinition.getType(), eitherStatus.right().value().name());
                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
-
-            } else {
-                GroupTypeData groupTypeData = eitherStatus.left().value();
-
-                String uniqueId = groupTypeData.getUniqueId();
-                Either<GroupTypeDefinition, StorageOperationStatus> groupTypeRes = this.getGroupType(uniqueId, true);
-
-                if (groupTypeRes.isRight()) {
-                    BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError(GET_FLOW_CONTEXT, groupTypeDefinition.getType(), eitherStatus.right().value().name());
-                } else {
-                    List<CapabilityTypeDefinition> groupCapTypes = groupTypeDefinition.getCapabilityTypes();
-                    if (!CollectionUtils.isEmpty(groupCapTypes)) {
-                        Optional<TitanOperationStatus> firstFailure = connectToCapabilityType(groupTypeData, groupCapTypes);
-                        if (firstFailure.isPresent()) {
-                            groupTypeRes = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(firstFailure.get()));
-                        }
-                    }
-                }
-
-                result = groupTypeRes;
-
+            }
+            else {
+                result = getGroupType(eitherStatus.left().value().getUniqueId(), inTransaction);
             }
 
             return result;
 
         } finally {
-            handleTransactionCommitRollback(inTransaction, result);
+            titanGenericDao.handleTransactionCommitRollback(inTransaction, result);
         }
 
     }
 
-
     @Override
-    public Either<GroupTypeDefinition, StorageOperationStatus> upgradeGroupType(GroupTypeDefinition groupTypeDefinitionNew, GroupTypeDefinition groupTypeDefinitionOld) {
-        return upgradeGroupType(groupTypeDefinitionOld, groupTypeDefinitionNew, false);
+    public Either<GroupTypeDefinition, StorageOperationStatus> updateGroupType(GroupTypeDefinition updatedGroupType, GroupTypeDefinition currGroupType) {
+        log.debug("updating group type {}", updatedGroupType.getType());
+        return updateGroupTypeOnGraph(updatedGroupType, currGroupType);
     }
-
-    @Override
-    public Either<GroupTypeDefinition, StorageOperationStatus> upgradeGroupType(GroupTypeDefinition groupTypeDefinitionNew, GroupTypeDefinition groupTypeDefinitionOld, boolean inTransaction) {
-        Either<GroupTypeDefinition, StorageOperationStatus> result = Either.left(groupTypeDefinitionNew);
-
-        try {
-            // dr2032:
-            // Right now upgrade Group is used only to ensure that already existing group type is connected by DERRIVED_FROM edge with it's parent
-            // We don't need to use for a while new node definition since following group type upgrade is not supported.
-            if (!Strings.isNullOrEmpty(groupTypeDefinitionOld.getDerivedFrom())) {
-                result = ensureExsitanceDerivedFromEdge(groupTypeDefinitionOld);
+    
+    
+    public Either<GroupTypeDefinition, StorageOperationStatus> validateUpdateProperties(GroupTypeDefinition groupTypeDefinition) {
+        TitanOperationStatus error = null;
+        if (CollectionUtils.isNotEmpty(groupTypeDefinition.getProperties()) && !Strings.isNullOrEmpty(groupTypeDefinition.getDerivedFrom())) {
+            Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesRes = 
+                                        getAllGroupTypePropertiesFromAllDerivedFrom(groupTypeDefinition.getDerivedFrom());
+            if (allPropertiesRes.isRight() && !allPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
+                error = allPropertiesRes.right().value();
+                log.debug("Couldn't fetch derived from property nodes for group type {}, error: {}", groupTypeDefinition.getType(), error);
             }
-        } finally {
-            handleTransactionCommitRollback(inTransaction, result);
+            if (error == null && !allPropertiesRes.left().value().isEmpty()) {
+                Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertiesRes = propertyOperation.validatePropertiesUniqueness(allPropertiesRes.left().value(),
+                        groupTypeDefinition.getProperties());
+                if (validatePropertiesRes.isRight()) {
+                    error = validatePropertiesRes.right().value();
+                }
+            }
         }
-
-        return result;
+        if (error == null) {
+            return Either.left(groupTypeDefinition);
+        }
+        return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
+    }
+    
+    private Either<Map<String, PropertyDefinition>, TitanOperationStatus> getAllGroupTypePropertiesFromAllDerivedFrom(String firstParentType) {
+        return titanGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), firstParentType, GroupTypeData.class)
+                    .left()
+                    .bind(parentGroup -> propertyOperation.getAllTypePropertiesFromAllDerivedFrom(parentGroup.getUniqueId(), NodeTypeEnum.GroupType, GroupTypeData.class));
     }
 
-    private Optional<TitanOperationStatus> connectToCapabilityType(GroupTypeData groupTypeData, List<CapabilityTypeDefinition> groupCapTypes) {
-        return groupCapTypes.stream()
-                .map(groupCapTypeDef -> connectTo(groupTypeData, groupCapTypeDef))
+
+    private StorageOperationStatus mergeCapabilities(GroupTypeDefinition groupTypeDef) {
+        Map<String, CapabilityDefinition> updatedGroupTypeCapabilities = groupTypeDef.getCapabilities();
+        Map<String, CapabilityDefinition> newGroupTypeCapabilities;
+        Either<List<CapabilityDefinition>, StorageOperationStatus> oldCapabilitiesRes = getCapablities(groupTypeDef.getUniqueId());
+        if (oldCapabilitiesRes.isRight()) {
+            StorageOperationStatus status = oldCapabilitiesRes.right().value();
+            if (status == StorageOperationStatus.NOT_FOUND) {
+                newGroupTypeCapabilities = updatedGroupTypeCapabilities;
+            }
+            else {
+                return status;
+            }
+        }
+        else {
+            Map<String, CapabilityDefinition> oldCapabilities = asCapabilitiesMap(oldCapabilitiesRes.left().value());
+            newGroupTypeCapabilities = collectNewCapabilities(updatedGroupTypeCapabilities, oldCapabilities);
+
+            for(Map.Entry<String, CapabilityDefinition> oldEntry: oldCapabilities.entrySet()) {
+                String key = oldEntry.getKey();
+                CapabilityDefinition newCapDef = updatedGroupTypeCapabilities != null? updatedGroupTypeCapabilities.get(key): null;
+                CapabilityDefinition oldCapDef = oldEntry.getValue();
+
+                StorageOperationStatus deleteCapResult = deleteOutdatedCapability(newGroupTypeCapabilities, newCapDef, oldCapDef);
+                if(deleteCapResult != StorageOperationStatus.OK) {
+                    return deleteCapResult;
+                }
+            }
+        }
+
+        TitanOperationStatus createCapResult = createCapabilities(new GroupTypeData(groupTypeDef), newGroupTypeCapabilities);
+        return DaoStatusConverter.convertTitanStatusToStorageStatus(createCapResult);
+    }
+
+    /**
+     * @param newGroupTypeCapabilities
+     * @param newCapDef
+     * @param oldCapDef
+     * @return 
+     */
+    private StorageOperationStatus deleteOutdatedCapability(Map<String, CapabilityDefinition> newGroupTypeCapabilities, CapabilityDefinition newCapDef, CapabilityDefinition oldCapDef) {
+        if(!isUpdateAllowed(newCapDef, oldCapDef)) {
+            return StorageOperationStatus.MATCH_NOT_FOUND;
+        }
+
+        if (!TypeCompareUtils.capabilityEquals(oldCapDef, newCapDef)) {
+            StorageOperationStatus deleteCapResult = capabilityOperation.deleteCapability(oldCapDef);
+
+            if(deleteCapResult == StorageOperationStatus.OK) {
+                newGroupTypeCapabilities.put(newCapDef.getName(), newCapDef);
+            }
+            else {
+                return deleteCapResult;
+            }
+        }
+        
+        return StorageOperationStatus.OK;
+    }
+
+    private boolean isUpdateAllowed(CapabilityDefinition newCapDef, CapabilityDefinition oldCapDef) {
+        if (newCapDef == null) {
+            log.error("#upsertCapabilities - Failed due to attempt to delete the capability with id {}", oldCapDef.getUniqueId());
+            return false;
+        }
+
+        if (newCapDef.getType() == null || !newCapDef.getType().equals(oldCapDef.getType())) {
+            log.error("#upsertCapabilities - Failed due to attempt to change type of the capability with id {}", oldCapDef.getUniqueId());
+            return false;
+        }
+        
+        return true;
+    }
+
+    /**
+     * @param updatedGroupTypeCapabilities
+     * @param oldCapabilities
+     * @return
+     */
+    private Map<String, CapabilityDefinition> collectNewCapabilities(Map<String, CapabilityDefinition> updatedGroupTypeCapabilities, Map<String, CapabilityDefinition> oldCapabilities) {
+        return updatedGroupTypeCapabilities != null? updatedGroupTypeCapabilities.entrySet().stream()
+                .filter(entry -> !oldCapabilities.containsKey(entry.getKey()))
+                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue) ): null;
+    }
+
+    private TitanOperationStatus createCapabilities(GroupTypeData groupTypeData, Map<String, CapabilityDefinition> groupCapabilities) {
+        if (MapUtils.isEmpty(groupCapabilities)) {
+            return TitanOperationStatus.OK;
+        }
+        
+        return groupCapabilities.values().stream()
+                .map(v -> createCapability(groupTypeData, v))
                 .filter(Either::isRight)
                 .findFirst()
-                .map(either -> either.right().value());
+                .map(either -> either.right().value())
+                .orElse(TitanOperationStatus.OK);
     }
 
-    private Either<GraphRelation, TitanOperationStatus> connectTo(GroupTypeData groupTypeData, CapabilityTypeDefinition groupCapTypeDef) {
-        Either<CapabilityTypeData, TitanOperationStatus> eitherCapData = capabilityTypeOperation.getCapabilityTypeByType(groupCapTypeDef.getType());
-        if (eitherCapData.isLeft()) {
-            return titanGenericDao.createRelation(groupTypeData, eitherCapData.left().value(), GraphEdgeLabels.GROUP_TYPE_CAPABILITY_TYPE, null);
+    private Either<GraphRelation, TitanOperationStatus> createCapability(GroupTypeData groupTypeData, CapabilityDefinition  capabilityDef) {
+        Either<CapabilityTypeDefinition, TitanOperationStatus> eitherCapData = capabilityTypeOperation.getCapabilityTypeByType(capabilityDef.getType());
+        return eitherCapData
+                .left()
+                .map(CapabilityTypeData::new)
+                .left()
+                .bind(capTypeData -> capabilityOperation.addCapabilityToGraph(groupTypeData.getUniqueId(), capTypeData, capabilityDef))
+                .left()
+                .bind(capData -> connectToCapability(groupTypeData, capData, capabilityDef.getName()));
+    }
+
+
+    /**
+     * Get capability with all relevant properties
+     * @param groupTypeId
+     * @return
+     */
+    private Either<List<CapabilityDefinition>, StorageOperationStatus> getCapablities(String groupTypeId) {
+        Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus> groupCapabilitiesOnGraph =
+                titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupType), groupTypeId, GraphEdgeLabels.GROUP_TYPE_CAPABILITY, NodeTypeEnum.Capability, CapabilityData.class, true);
+
+        if (groupCapabilitiesOnGraph.isRight()) {
+            TitanOperationStatus capabilityStatus = groupCapabilitiesOnGraph.right().value();
+            if (capabilityStatus == TitanOperationStatus.NOT_FOUND) {
+                return Either.left(Collections.emptyList());
+            }
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(capabilityStatus));
         }
 
-        return Either.right(eitherCapData.right().value());
+        List<ImmutablePair<CapabilityData, GraphEdge>> groupCapabilites = groupCapabilitiesOnGraph.left().value();
+        groupCapabilites.forEach(this::fillCapabilityName);
+
+        return capabilityOperation.getCapabilitiesWithProps(groupCapabilites)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
     }
 
+    private void fillCapabilityName(ImmutablePair<CapabilityData, GraphEdge> pair) {
+        pair.getLeft().getCapabilityDataDefinition().setName((String)pair.getRight().getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()));
+    }
+
+    private Either<GraphRelation, TitanOperationStatus> connectToCapability(GroupTypeData groupTypeData, CapabilityData capabilityData, String capabilityName) {
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), capabilityName);
+
+        return titanGenericDao.createRelation(groupTypeData, capabilityData, GraphEdgeLabels.GROUP_TYPE_CAPABILITY, properties);
+    }
+
+
     public List<GroupTypeDefinition> getAllGroupTypes(Set<String> excludedGroupTypes) {
         Map<String, Map.Entry<TitanPredicate, Object>> predicateCriteria = buildNotInPredicate(GraphPropertiesDictionary.TYPE.getProperty(), excludedGroupTypes);
         List<GroupTypeData> groupTypes = titanGenericDao.getByCriteriaWithPredicate(NodeTypeEnum.GroupType, predicateCriteria, GroupTypeData.class)
                 .left()
-                .on(this::onTitanAccessError);
-
+                .on(operationUtils::onTitanOperationFailure);
         return convertGroupTypesToDefinition(groupTypes);
     }
 
@@ -199,54 +316,44 @@
                 .collect(Collectors.toList());
     }
 
-    private List<GroupTypeData> onTitanAccessError(TitanOperationStatus toe) {
-        throw new StorageException(
-                DaoStatusConverter.convertTitanStatusToStorageStatus(toe));
-    }
 
-
-    public Either<GroupTypeDefinition, TitanOperationStatus> getGroupTypeByUid(String uniqueId) {
-
-        Either<GroupTypeDefinition, TitanOperationStatus> result = null;
-
-        Either<GroupTypeData, TitanOperationStatus> groupTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupType), uniqueId, GroupTypeData.class);
-
-        if (groupTypesRes.isRight()) {
-            TitanOperationStatus status = groupTypesRes.right().value();
-            log.debug("Group type {} cannot be found in graph. status is {}", uniqueId, status);
-            return Either.right(status);
-        }
-
-        GroupTypeData gtData = groupTypesRes.left().value();
-        GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition(gtData.getGroupTypeDataDefinition());
-
-        TitanOperationStatus propertiesStatus = propertyOperation.fillProperties(uniqueId, NodeTypeEnum.GroupType, properList -> groupTypeDefinition.setProperties(properList));
-
-        if (propertiesStatus != TitanOperationStatus.OK) {
-            log.error("Failed to fetch properties of capability type {}", uniqueId);
-            return Either.right(propertiesStatus);
-        }
-
-        result = Either.left(groupTypeDefinition);
-
-        return result;
-    }
-
-    @Override
-    public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId) {
-
-        return getGroupType(uniqueId, false);
-
+    public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByUid(String uniqueId) {
+        log.debug("#getGroupTypeByUid - fetching group type with id {}", uniqueId);
+        return titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupType), uniqueId, GroupTypeData.class)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus)
+                .left()
+                .bind(groupType -> buildGroupTypeDefinition(uniqueId, groupType));
     }
 
     @Override
     public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId, boolean inTransaction) {
-        return getElementType(this::getGroupTypeByUid, uniqueId, inTransaction);
+        Either<GroupTypeDefinition, StorageOperationStatus> result = null;
+        try {
+
+            Either<GroupTypeDefinition, StorageOperationStatus> ctResult = getGroupTypeByUid(uniqueId);
+
+            if (ctResult.isRight()) {
+                StorageOperationStatus status = ctResult.right().value();
+                if (status != StorageOperationStatus.NOT_FOUND) {
+                    log.error("Failed to retrieve information on element uniqueId: {}. status is {}", uniqueId, status);
+                }
+                result = Either.right(ctResult.right().value());
+                return result;
+            }
+
+            result = Either.left(ctResult.left().value());
+
+            return result;
+        } finally {
+            titanGenericDao.handleTransactionCommitRollback(inTransaction, result);
+        }
+
     }
 
     @Override
     public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String type) {
-        return getLatestGroupTypeByType(type, false);
+        return getLatestGroupTypeByType(type, true);
     }
 
     @Override
@@ -268,21 +375,98 @@
                 return result;
             }
 
-            Either<List<GroupTypeData>, TitanOperationStatus> groupTypeEither = titanGenericDao.getByCriteria(NodeTypeEnum.GroupType, properties, GroupTypeData.class);
+            Either<List<GroupTypeData>, StorageOperationStatus> groupTypeEither = titanGenericDao.getByCriteria(NodeTypeEnum.GroupType, properties, GroupTypeData.class)
+                    .right()
+                    .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
             if (groupTypeEither.isRight()) {
-                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(groupTypeEither.right().value()));
+                result = Either.right(groupTypeEither.right().value());
             } else {
-                GroupTypeDataDefinition dataDefinition = groupTypeEither.left().value().stream().map(e -> e.getGroupTypeDataDefinition()).findFirst().get();
-                result = getGroupType(dataDefinition.getUniqueId(), inTransaction);
-            }
+                GroupTypeDataDefinition dataDefinition = groupTypeEither.left().value().stream()
+                        .map(GroupTypeData::getGroupTypeDataDefinition)
+                        .findFirst()
+                        .get();
+                result = getGroupTypeByUid(dataDefinition.getUniqueId());
 
+            }
             return result;
 
         } finally {
-            handleTransactionCommitRollback(inTransaction, result);
+            titanGenericDao.handleTransactionCommitRollback(inTransaction, result);
         }
     }
 
+    private Either<GroupTypeDefinition, StorageOperationStatus> buildGroupTypeDefinition(String uniqueId, GroupTypeData groupTypeNode) {
+        GroupTypeDefinition groupType = new GroupTypeDefinition(groupTypeNode.getGroupTypeDataDefinition());
+        return fillDerivedFrom(uniqueId, groupType)
+                .left()
+                .map(derivedFrom -> fillProperties(uniqueId, groupType, derivedFrom))
+                .left()
+                .bind(props -> fillCapabilities(uniqueId, groupType));
+    }
+    
+    private Either<GroupTypeDefinition, StorageOperationStatus> fillCapabilities(String uniqueId, GroupTypeDefinition groupType) {
+        return getCapablities(uniqueId)
+                .left()
+                .map(capabilities -> {
+                    groupType.setCapabilities(asCapabilitiesMap(capabilities));
+                    return groupType;
+                });
+    }
+
+    private Either<GroupTypeData, StorageOperationStatus> fillDerivedFrom(String uniqueId, GroupTypeDefinition groupType) {
+        log.debug("#fillDerivedFrom - fetching group type {} derived node", groupType.getType());
+        return derivedFromOperation.getDerivedFromChild(uniqueId, NodeTypeEnum.GroupType, GroupTypeData.class)
+                .right()
+                .bind(this::handleDerivedFromNotExist)
+                .left()
+                .map(derivedFrom -> setDerivedFrom(groupType, derivedFrom));
+
+    }
+
+    private Either<List<PropertyDefinition>, StorageOperationStatus> fillProperties(String uniqueId, GroupTypeDefinition groupType, GroupTypeData derivedFromNode) {
+        log.debug("#fillProperties - fetching all properties for group type {}", groupType.getType());
+        return propertyOperation.findPropertiesOfNode(NodeTypeEnum.GroupType, uniqueId)
+                .right()
+                .bind(this::handleGroupTypeHasNoProperties)
+                .left()
+                .bind(propsMap -> fillDerivedFromProperties(groupType, derivedFromNode, new ArrayList<>(propsMap.values())));
+    }
+
+    Either<Map<String, PropertyDefinition>, StorageOperationStatus> handleGroupTypeHasNoProperties(TitanOperationStatus err) {
+        if (err == TitanOperationStatus.NOT_FOUND) {
+            return Either.left(new HashMap<>());
+        }
+        return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(err));
+    }
+
+    private Either<List<PropertyDefinition>, StorageOperationStatus> fillDerivedFromProperties(GroupTypeDefinition groupType, GroupTypeData derivedFromNode, List<PropertyDefinition> groupTypeDirectProperties) {
+        if (derivedFromNode == null) {
+            groupType.setProperties(groupTypeDirectProperties);
+            return Either.left(groupTypeDirectProperties);
+        }
+        log.debug("#fillDerivedFromProperties - fetching all properties of derived from chain for group type {}", groupType.getType());
+        return propertyOperation.getAllPropertiesRec(derivedFromNode.getUniqueId(), NodeTypeEnum.GroupType, GroupTypeData.class)
+                .left()
+                .map(derivedFromProps -> {groupTypeDirectProperties.addAll(derivedFromProps); return groupTypeDirectProperties;})
+                .left()
+                .map(allProps -> {groupType.setProperties(allProps);return allProps;});
+    }
+
+    private Either<GroupTypeData, StorageOperationStatus> handleDerivedFromNotExist(StorageOperationStatus err) {
+        if (err == StorageOperationStatus.NOT_FOUND) {
+            return Either.left(null);
+        }
+        return Either.right(err);
+    }
+
+    private GroupTypeData setDerivedFrom(GroupTypeDefinition groupTypeDefinition, GroupTypeData derivedFrom) {
+        if (derivedFrom != null) {
+            groupTypeDefinition.setDerivedFrom(derivedFrom.getGroupTypeDataDefinition().getType());
+        }
+        return derivedFrom;
+    }
+
+
     @Override
     public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String type, String version) {
         return getGroupTypeByTypeAndVersion(type, version, false);
@@ -313,7 +497,7 @@
 
         log.debug("Got group type {}", groupTypeDefinition);
 
-        String ctUniqueId = UniqueIdBuilder.buildGroupTypeUid(groupTypeDefinition.getType(), groupTypeDefinition.getVersion());
+        String ctUniqueId = UniqueIdBuilder.buildGroupTypeUid(groupTypeDefinition.getType(), groupTypeDefinition.getVersion(), "grouptype");
 
         GroupTypeData groupTypeData = buildGroupTypeData(groupTypeDefinition, ctUniqueId);
 
@@ -343,6 +527,14 @@
                 return Either.right(createRelation.right().value());
             }
         }
+        
+        Map<String, CapabilityDefinition> groupCapTypes = groupTypeDefinition.getCapabilities();
+        if (!MapUtils.isEmpty(groupCapTypes)) {
+            TitanOperationStatus status = createCapabilities(groupTypeData, groupCapTypes);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(status);
+            }
+        }
 
         return Either.left(createGTResult.left().value());
 
@@ -369,55 +561,6 @@
         }
     }
 
-
-    private Either<GroupTypeDefinition, StorageOperationStatus> ensureExsitanceDerivedFromEdge(GroupTypeDefinition groupTypeDefinition) {
-        Either<GroupTypeDefinition, StorageOperationStatus> result = Either.left(groupTypeDefinition);
-
-        GroupTypeData childGroupType = null;
-        GroupTypeData parentGroupType = null;
-
-        Either<GroupTypeData, TitanOperationStatus> childGroupTypeResult =
-                titanGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), groupTypeDefinition.getType(), GroupTypeData.class);
-        if (childGroupTypeResult.isRight()) {
-            result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childGroupTypeResult.right().value()));
-            log.debug("Filed to find GroupType with type {}, status is {}.", groupTypeDefinition.getType(), childGroupTypeResult);
-        } else {
-            childGroupType = childGroupTypeResult.left().value();
-        }
-
-
-        if (result.isLeft()) {
-            Either<GroupTypeData, TitanOperationStatus> parentGroupTypeResult =
-                    titanGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), groupTypeDefinition.getDerivedFrom(), GroupTypeData.class);
-            if (parentGroupTypeResult.isRight()) {
-                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentGroupTypeResult.right().value()));
-                log.debug("Filed to find GroupType with type {}, status is {}.", groupTypeDefinition.getDerivedFrom(), parentGroupTypeResult);
-            } else {
-                parentGroupType = parentGroupTypeResult.left().value();
-            }
-        }
-
-
-        if (childGroupType != null && parentGroupType != null) {
-            Either<Edge, TitanOperationStatus> edgeDerivedFromResult = titanGenericDao.getEdgeByNodes(childGroupType, parentGroupType, GraphEdgeLabels.DERIVED_FROM);
-            if (edgeDerivedFromResult.isLeft()) {
-                log.debug("It was found relation {}. Don't need to create the edge.", edgeDerivedFromResult.left().value());
-            } else {
-                Either<GraphRelation, TitanOperationStatus> createRelationResult = titanGenericDao.createRelation(childGroupType, parentGroupType, GraphEdgeLabels.DERIVED_FROM, null);
-                log.debug("After create relation between Group Type with id {} to its parent with id {}, status is {}.",
-                        childGroupType.getKeyValueId().getValue(), parentGroupType.getKeyValueId().getValue(), createRelationResult);
-                if (createRelationResult.isRight()) {
-                    result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createRelationResult.right().value()));
-                }
-            }
-
-        }
-
-
-        return result;
-    }
-
-
     private GroupTypeData buildGroupTypeData(GroupTypeDefinition groupTypeDefinition, String ctUniqueId) {
 
         GroupTypeData groupTypeData = new GroupTypeData(groupTypeDefinition);
@@ -434,7 +577,7 @@
     }
 
     public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, String parentCandidateType) {
-        Map<String, Object> propertiesToMatch = new HashMap<String, Object>();
+        Map<String, Object> propertiesToMatch = new HashMap<>();
         propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childCandidateType);
         Either<List<CapabilityTypeData>, TitanOperationStatus> getResponse = titanGenericDao.getByCriteria(NodeTypeEnum.CapabilityType, propertiesToMatch, CapabilityTypeData.class);
         if (getResponse.isRight()) {
@@ -454,7 +597,7 @@
                     log.debug("Couldn't fetch derived from node for capability type {}, error: {}", childCandidateType, titanOperationStatus);
                     return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus));
                 } else {
-                    log.debug("Derived from node is not found for type {} - this is OK for root capability.");
+                    log.debug("Derived from node is not found for type {} - this is OK for root capability.", childCandidateType);
                     return Either.left(false);
                 }
             }
@@ -471,20 +614,99 @@
         log.error("Detected a cycle of \"derived from\" edges starting at capability type node {}", childUniqueId);
         return Either.right(StorageOperationStatus.GENERAL_ERROR);
     }
-
+    
     /**
-     * FOR TEST ONLY
-     *
-     * @param propertyOperation
+     * @param list
+     * @return
      */
-    public void setPropertyOperation(PropertyOperation propertyOperation) {
-        this.propertyOperation = propertyOperation;
+    private Map<String, CapabilityDefinition> asCapabilitiesMap(List<CapabilityDefinition> list) {
+        return list.stream()
+                .collect(Collectors.toMap(CapabilityDefinition::getName, Function.identity()));
     }
 
-    @Override
-    public Either<GroupTypeData, TitanOperationStatus> getLatestGroupTypeByNameFromGraph(String name) {
 
-        return null;
+    private Either<GroupTypeDefinition, StorageOperationStatus> updateGroupTypeOnGraph(GroupTypeDefinition updatedGroupType, GroupTypeDefinition currGroupType) {
+        updateGroupTypeData(updatedGroupType, currGroupType);
+        return titanGenericDao.updateNode(new GroupTypeData(updatedGroupType), GroupTypeData.class)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus)
+                .left()
+                .bind(updatedNode -> updateGroupProperties(updatedGroupType.getUniqueId(), updatedGroupType.getProperties()))
+                .left()
+                .bind(updatedProperties -> updateGroupDerivedFrom(updatedGroupType, currGroupType.getDerivedFrom()))
+                .right()
+                .bind(result -> TypeOperations.mapOkStatus(result, null))
+                .left()
+                .bind(updatedDerivedFrom -> TypeOperations.mapOkStatus(mergeCapabilities(updatedGroupType), updatedGroupType))
+                .left()
+                .bind(def -> getGroupTypeByUid(def.getUniqueId()));
+    }
+    
+
+    private Either<Map<String, PropertyData>, StorageOperationStatus> updateGroupProperties(String groupId, List<PropertyDefinition> properties) {
+        log.debug("#updateGroupProperties - updating group type properties for group type with id {}", groupId);
+        Map<String, PropertyDefinition> mapProperties = properties != null? properties.stream()
+                .collect(Collectors.toMap(PropertyDefinition::getName, Function.identity())): null;
+        return propertyOperation.mergePropertiesAssociatedToNode(NodeTypeEnum.GroupType, groupId, mapProperties)
+                .right()
+                .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+    }
+
+
+
+    private Either<GraphRelation, StorageOperationStatus> updateGroupDerivedFrom(GroupTypeDefinition updatedGroupType, String currDerivedFromGroupType) {
+        
+        String groupTypeId = updatedGroupType.getUniqueId();
+        if (StringUtils.equals(updatedGroupType.getDerivedFrom(), currDerivedFromGroupType)) {
+            return Strings.isNullOrEmpty(currDerivedFromGroupType)? 
+                    Either.right(StorageOperationStatus.OK):
+                        getLatestGroupTypeByType(currDerivedFromGroupType, true)
+                        .left()
+                        .map(def -> null);
+        }
+        
+        StorageOperationStatus status = isLegalToReplaceParent(currDerivedFromGroupType, updatedGroupType.getDerivedFrom(), updatedGroupType.getType());
+        if ( status != StorageOperationStatus.OK) {
+            return Either.right(status);
+        }
+
+        log.debug("#updateGroupDerivedFrom - updating group derived from relation for group type with id {}. old derived type {}. new derived type {}", groupTypeId, currDerivedFromGroupType, updatedGroupType.getDerivedFrom());
+        StorageOperationStatus deleteDerivedRelationStatus = deleteDerivedFromGroupType(groupTypeId, currDerivedFromGroupType);
+        if (deleteDerivedRelationStatus != StorageOperationStatus.OK) {
+            return Either.right(deleteDerivedRelationStatus);
+        }
+        return addDerivedFromRelation(updatedGroupType, groupTypeId);
+    }
+
+    private StorageOperationStatus isLegalToReplaceParent(String oldTypeParent, String newTypeParent, String childType) {
+        return derivedFromOperation.isUpdateParentAllowed(oldTypeParent, newTypeParent, childType, NodeTypeEnum.GroupType, GroupTypeData.class, t -> t.getGroupTypeDataDefinition().getType());
+    }
+    
+    private Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(GroupTypeDataDefinition groupTypeDef, String gtUniqueId) {
+        String derivedFrom = groupTypeDef.getDerivedFrom();
+        if (derivedFrom == null) {
+            return Either.left(null);
+        }
+        log.debug("#addDerivedFromRelationBefore - adding derived from relation between group type {} to its parent {}", groupTypeDef.getType(), derivedFrom);
+        return this.getLatestGroupTypeByType(derivedFrom, true)
+                .left()
+                .bind(derivedFromGroup -> derivedFromOperation.addDerivedFromRelation(gtUniqueId, derivedFromGroup.getUniqueId(), NodeTypeEnum.GroupType));
+    }
+
+    private StorageOperationStatus deleteDerivedFromGroupType(String groupTypeId, String derivedFromType) {
+        if (derivedFromType == null) {
+            return StorageOperationStatus.OK;
+        }
+        log.debug("#deleteDerivedFromGroupType - deleting derivedFrom relation for group type with id {} and its derived type {}", groupTypeId, derivedFromType);
+        return getLatestGroupTypeByType(derivedFromType, true)
+                .either(derivedFromNode -> derivedFromOperation.removeDerivedFromRelation(groupTypeId, derivedFromNode.getUniqueId(), NodeTypeEnum.GroupType),
+                        err -> err);
+    }
+
+    private void updateGroupTypeData(GroupTypeDefinition updatedTypeDefinition, GroupTypeDefinition currTypeDefinition) {
+        updatedTypeDefinition.setUniqueId(currTypeDefinition.getUniqueId());
+        updatedTypeDefinition.setCreationTime(currTypeDefinition.getCreationTime());
+        updatedTypeDefinition.setModificationTime(System.currentTimeMillis());
     }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java
index 7b7ead5..6d050af 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java
@@ -20,11 +20,7 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
@@ -43,432 +39,432 @@
 import org.openecomp.sdc.be.resources.data.HeatParameterData;
 import org.openecomp.sdc.be.resources.data.HeatParameterValueData;
 import org.openecomp.sdc.be.resources.data.UniqueIdData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
-import fj.data.Either;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Component("heat-parameter-operation")
 public class HeatParametersOperation implements IHeatParametersOperation {
 
-	public static final String EMPTY_VALUE = null;
+    public static final String EMPTY_VALUE = null;
 
-	private static Logger log = LoggerFactory.getLogger(HeatParametersOperation.class.getName());
+    private static final Logger log = Logger.getLogger(HeatParametersOperation.class.getName());
 
-	@javax.annotation.Resource
-	private TitanGenericDao titanGenericDao;
+    @javax.annotation.Resource
+    private TitanGenericDao titanGenericDao;
 
-	public TitanGenericDao getTitanGenericDao() {
-		return titanGenericDao;
-	}
+    public TitanGenericDao getTitanGenericDao() {
+        return titanGenericDao;
+    }
 
-	public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
-		this.titanGenericDao = titanGenericDao;
-	}
+    public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
+        this.titanGenericDao = titanGenericDao;
+    }
 
-	public StorageOperationStatus getHeatParametersOfNode(NodeTypeEnum nodeType, String uniqueId, List<HeatParameterDefinition> properties) {
+    public StorageOperationStatus getHeatParametersOfNode(NodeTypeEnum nodeType, String uniqueId, List<HeatParameterDefinition> properties) {
 
-		Either<List<ImmutablePair<HeatParameterData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.HEAT_PARAMETER, NodeTypeEnum.HeatParameter,
-				HeatParameterData.class);
+        Either<List<ImmutablePair<HeatParameterData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.HEAT_PARAMETER, NodeTypeEnum.HeatParameter,
+                HeatParameterData.class);
 
-		if (childrenNodes.isRight()) {
-			TitanOperationStatus status = childrenNodes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.OK;
-			}
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
+        if (childrenNodes.isRight()) {
+            TitanOperationStatus status = childrenNodes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.OK;
+            }
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
 
-		List<ImmutablePair<HeatParameterData, GraphEdge>> values = childrenNodes.left().value();
-		if (values != null) {
+        List<ImmutablePair<HeatParameterData, GraphEdge>> values = childrenNodes.left().value();
+        if (values != null) {
 
-			for (ImmutablePair<HeatParameterData, GraphEdge> immutablePair : values) {
-				GraphEdge edge = immutablePair.getValue();
-				String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
-				if (log.isDebugEnabled())
-					log.debug("Property {} is associated to node {}", propertyName, uniqueId);
-				HeatParameterData propertyData = immutablePair.getKey();
-				HeatParameterDefinition propertyDefinition = convertParameterDataToParameterDefinition(propertyData, propertyName, uniqueId);
+            for (ImmutablePair<HeatParameterData, GraphEdge> immutablePair : values) {
+                GraphEdge edge = immutablePair.getValue();
+                String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
+                if (log.isDebugEnabled())
+                    log.debug("Property {} is associated to node {}", propertyName, uniqueId);
+                HeatParameterData propertyData = immutablePair.getKey();
+                HeatParameterDefinition propertyDefinition = convertParameterDataToParameterDefinition(propertyData, propertyName, uniqueId);
 
-				properties.add(propertyDefinition);
+                properties.add(propertyDefinition);
 
-				if (log.isTraceEnabled()) {
-					log.trace("getHeatParametersOfNode - property {} associated to node {}", propertyDefinition, uniqueId);
-				}
-			}
+                if (log.isTraceEnabled()) {
+                    log.trace("getHeatParametersOfNode - property {} associated to node {}", propertyDefinition, uniqueId);
+                }
+            }
 
-		}
+        }
 
-		return StorageOperationStatus.OK;
-	}
+        return StorageOperationStatus.OK;
+    }
 
-	public StorageOperationStatus getParametersValueNodes(NodeTypeEnum parentNodeType, String parentUniqueId, List<HeatParameterValueData> heatValues) {
+    public StorageOperationStatus getParametersValueNodes(NodeTypeEnum parentNodeType, String parentUniqueId, List<HeatParameterValueData> heatValues) {
 
-		Either<List<ImmutablePair<HeatParameterValueData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentUniqueId, GraphEdgeLabels.PARAMETER_VALUE,
-				NodeTypeEnum.HeatParameterValue, HeatParameterValueData.class);
+        Either<List<ImmutablePair<HeatParameterValueData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentUniqueId, GraphEdgeLabels.PARAMETER_VALUE,
+                NodeTypeEnum.HeatParameterValue, HeatParameterValueData.class);
 
-		if (childrenNodes.isRight()) {
-			TitanOperationStatus status = childrenNodes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.OK;
-			}
-			return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-		}
+        if (childrenNodes.isRight()) {
+            TitanOperationStatus status = childrenNodes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.OK;
+            }
+            return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+        }
 
-		List<ImmutablePair<HeatParameterValueData, GraphEdge>> values = childrenNodes.left().value();
-		if (values != null) {
+        List<ImmutablePair<HeatParameterValueData, GraphEdge>> values = childrenNodes.left().value();
+        if (values != null) {
 
-			for (ImmutablePair<HeatParameterValueData, GraphEdge> immutablePair : values) {
-				GraphEdge edge = immutablePair.getValue();
-				String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
-				log.trace("Heat value {} is associated to node {}", propertyName,parentUniqueId);
-				HeatParameterValueData propertyData = immutablePair.getKey();
+            for (ImmutablePair<HeatParameterValueData, GraphEdge> immutablePair : values) {
+                GraphEdge edge = immutablePair.getValue();
+                String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
+                log.trace("Heat value {} is associated to node {}", propertyName,parentUniqueId);
+                HeatParameterValueData propertyData = immutablePair.getKey();
 
-				heatValues.add(propertyData);
-			}
+                heatValues.add(propertyData);
+            }
 
-		}
+        }
 
-		return StorageOperationStatus.OK;
-	}
+        return StorageOperationStatus.OK;
+    }
 
-	@Override
-	public Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteAllHeatParametersAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) {
+    @Override
+    public Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteAllHeatParametersAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) {
 
-		List<HeatParameterDefinition> heatParams = new ArrayList<HeatParameterDefinition>();
-		StorageOperationStatus propertiesOfNodeRes = getHeatParametersOfNode(nodeType, uniqueId, heatParams);
+        List<HeatParameterDefinition> heatParams = new ArrayList<>();
+        StorageOperationStatus propertiesOfNodeRes = getHeatParametersOfNode(nodeType, uniqueId, heatParams);
 
-		if (!propertiesOfNodeRes.equals(StorageOperationStatus.OK) && !propertiesOfNodeRes.equals(StorageOperationStatus.NOT_FOUND)) {
-			return Either.right(propertiesOfNodeRes);
-		}
+        if (!propertiesOfNodeRes.equals(StorageOperationStatus.OK) && !propertiesOfNodeRes.equals(StorageOperationStatus.NOT_FOUND)) {
+            return Either.right(propertiesOfNodeRes);
+        }
 
-		for (HeatParameterDefinition propertyDefinition : heatParams) {
+        for (HeatParameterDefinition propertyDefinition : heatParams) {
 
-			String propertyUid = propertyDefinition.getUniqueId();
-			Either<HeatParameterData, TitanOperationStatus> deletePropertyRes = deleteHeatParameterFromGraph(propertyUid);
-			if (deletePropertyRes.isRight()) {
-				log.error("Failed to delete heat parameter with id {}", propertyUid);
-				TitanOperationStatus status = deletePropertyRes.right().value();
-				if (status == TitanOperationStatus.NOT_FOUND) {
-					status = TitanOperationStatus.INVALID_ID;
-				}
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
-			}
+            String propertyUid = propertyDefinition.getUniqueId();
+            Either<HeatParameterData, TitanOperationStatus> deletePropertyRes = deleteHeatParameterFromGraph(propertyUid);
+            if (deletePropertyRes.isRight()) {
+                log.error("Failed to delete heat parameter with id {}", propertyUid);
+                TitanOperationStatus status = deletePropertyRes.right().value();
+                if (status == TitanOperationStatus.NOT_FOUND) {
+                    status = TitanOperationStatus.INVALID_ID;
+                }
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+            }
 
-		}
+        }
 
-		log.debug("The heat parameters deleted from node {} are {}", uniqueId, heatParams);
-		return Either.left(heatParams);
-	}
+        log.debug("The heat parameters deleted from node {} are {}", uniqueId, heatParams);
+        return Either.left(heatParams);
+    }
 
-	@Override
-	public StorageOperationStatus deleteAllHeatValuesAssociatedToNode(NodeTypeEnum parentNodeType, String parentUniqueId) {
+    @Override
+    public StorageOperationStatus deleteAllHeatValuesAssociatedToNode(NodeTypeEnum parentNodeType, String parentUniqueId) {
 
-		List<HeatParameterValueData> heatValues = new ArrayList<HeatParameterValueData>();
-		StorageOperationStatus propertiesOfNodeRes = getParametersValueNodes(parentNodeType, parentUniqueId, heatValues);
+        List<HeatParameterValueData> heatValues = new ArrayList<>();
+        StorageOperationStatus propertiesOfNodeRes = getParametersValueNodes(parentNodeType, parentUniqueId, heatValues);
 
-		if (!propertiesOfNodeRes.equals(StorageOperationStatus.OK) && !propertiesOfNodeRes.equals(StorageOperationStatus.NOT_FOUND)) {
-			return propertiesOfNodeRes;
-		}
+        if (!propertiesOfNodeRes.equals(StorageOperationStatus.OK) && !propertiesOfNodeRes.equals(StorageOperationStatus.NOT_FOUND)) {
+            return propertiesOfNodeRes;
+        }
 
-		for (HeatParameterValueData propertyDefinition : heatValues) {
+        for (HeatParameterValueData propertyDefinition : heatValues) {
 
-			String propertyUid = (String) propertyDefinition.getUniqueId();
-			Either<HeatParameterValueData, TitanOperationStatus> deletePropertyRes = deleteHeatParameterValueFromGraph(propertyUid);
-			if (deletePropertyRes.isRight()) {
-				log.error("Failed to delete heat parameter value with id {}", propertyUid);
-				TitanOperationStatus status = deletePropertyRes.right().value();
-				if (status == TitanOperationStatus.NOT_FOUND) {
-					status = TitanOperationStatus.INVALID_ID;
-				}
-				return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
-			}
+            String propertyUid = (String) propertyDefinition.getUniqueId();
+            Either<HeatParameterValueData, TitanOperationStatus> deletePropertyRes = deleteHeatParameterValueFromGraph(propertyUid);
+            if (deletePropertyRes.isRight()) {
+                log.error("Failed to delete heat parameter value with id {}", propertyUid);
+                TitanOperationStatus status = deletePropertyRes.right().value();
+                if (status == TitanOperationStatus.NOT_FOUND) {
+                    status = TitanOperationStatus.INVALID_ID;
+                }
+                return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+            }
 
-		}
+        }
 
-		log.debug("The heat values deleted from node {} are {}" , parentUniqueId, heatValues);
-		return StorageOperationStatus.OK;
-	}
+        log.debug("The heat values deleted from node {} are {}" , parentUniqueId, heatValues);
+        return StorageOperationStatus.OK;
+    }
 
-	private Either<HeatParameterData, TitanOperationStatus> deleteHeatParameterFromGraph(String propertyId) {
-		log.debug("Before deleting heat parameter from graph {}" , propertyId);
-		return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.HeatParameter), propertyId, HeatParameterData.class);
-	}
+    private Either<HeatParameterData, TitanOperationStatus> deleteHeatParameterFromGraph(String propertyId) {
+        log.debug("Before deleting heat parameter from graph {}" , propertyId);
+        return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.HeatParameter), propertyId, HeatParameterData.class);
+    }
 
-	private Either<HeatParameterValueData, TitanOperationStatus> deleteHeatParameterValueFromGraph(String propertyId) {
-		log.debug("Before deleting heat parameter from graph {}" , propertyId);
-		return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.HeatParameterValue), propertyId, HeatParameterValueData.class);
-	}
+    private Either<HeatParameterValueData, TitanOperationStatus> deleteHeatParameterValueFromGraph(String propertyId) {
+        log.debug("Before deleting heat parameter from graph {}" , propertyId);
+        return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.HeatParameterValue), propertyId, HeatParameterValueData.class);
+    }
 
-	@Override
-	public StorageOperationStatus addPropertiesToGraph(List<HeatParameterDefinition> properties, String parentId, NodeTypeEnum nodeType) {
+    @Override
+    public StorageOperationStatus addPropertiesToGraph(List<HeatParameterDefinition> properties, String parentId, NodeTypeEnum nodeType) {
 
-		if (properties != null) {
-			for (HeatParameterDefinition propertyDefinition : properties) {
+        if (properties != null) {
+            for (HeatParameterDefinition propertyDefinition : properties) {
 
-				String propertyName = propertyDefinition.getName();
+                String propertyName = propertyDefinition.getName();
 
-				Either<HeatParameterData, TitanOperationStatus> addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, parentId, nodeType);
+                Either<HeatParameterData, TitanOperationStatus> addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, parentId, nodeType);
 
-				if (addPropertyToGraph.isRight()) {
-					return DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyToGraph.right().value());
-				}
-			}
-		}
+                if (addPropertyToGraph.isRight()) {
+                    return DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyToGraph.right().value());
+                }
+            }
+        }
 
-		return StorageOperationStatus.OK;
+        return StorageOperationStatus.OK;
 
-	}
+    }
 
-	@Override
-	public StorageOperationStatus updateHeatParameters(List<HeatParameterDefinition> properties) {
+    @Override
+    public StorageOperationStatus updateHeatParameters(List<HeatParameterDefinition> properties) {
 
-		if (properties == null) {
-			return StorageOperationStatus.OK;
-		}
-		for (HeatParameterDefinition property : properties) {
+        if (properties == null) {
+            return StorageOperationStatus.OK;
+        }
+        for (HeatParameterDefinition property : properties) {
 
-			HeatParameterData heatParameterData = new HeatParameterData(property);
-			Either<HeatParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(heatParameterData, HeatParameterData.class);
-			if (updateNode.isRight()) {
-				log.debug("failed to update heat parameter in graph. id = {}", property.getUniqueId());
-				return DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value());
-			}
-		}
+            HeatParameterData heatParameterData = new HeatParameterData(property);
+            Either<HeatParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(heatParameterData, HeatParameterData.class);
+            if (updateNode.isRight()) {
+                log.debug("failed to update heat parameter in graph. id = {}", property.getUniqueId());
+                return DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value());
+            }
+        }
 
-		return StorageOperationStatus.OK;
-	}
+        return StorageOperationStatus.OK;
+    }
 
-	public Either<HeatParameterData, TitanOperationStatus> addPropertyToGraph(String propertyName, HeatParameterDefinition propertyDefinition, String parentId, NodeTypeEnum nodeType) {
+    public Either<HeatParameterData, TitanOperationStatus> addPropertyToGraph(String propertyName, HeatParameterDefinition propertyDefinition, String parentId, NodeTypeEnum nodeType) {
 
-		UniqueIdData parentNode = new UniqueIdData(nodeType, parentId);
+        UniqueIdData parentNode = new UniqueIdData(nodeType, parentId);
 
-		propertyDefinition.setUniqueId(UniqueIdBuilder.buildHeatParameterUniqueId(parentId, propertyName));
-		HeatParameterData propertyData = new HeatParameterData(propertyDefinition);
+        propertyDefinition.setUniqueId(UniqueIdBuilder.buildHeatParameterUniqueId(parentId, propertyName));
+        HeatParameterData propertyData = new HeatParameterData(propertyDefinition);
 
-		log.debug("Before adding property to graph {}" , propertyData);
-		Either<HeatParameterData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, HeatParameterData.class);
-		log.debug("After adding property to graph {}" , propertyData);
-		if (createNodeResult.isRight()) {
-			TitanOperationStatus operationStatus = createNodeResult.right().value();
-			log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
-			return Either.right(operationStatus);
-		}
+        log.debug("Before adding property to graph {}" , propertyData);
+        Either<HeatParameterData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, HeatParameterData.class);
+        log.debug("After adding property to graph {}" , propertyData);
+        if (createNodeResult.isRight()) {
+            TitanOperationStatus operationStatus = createNodeResult.right().value();
+            log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
+            return Either.right(operationStatus);
+        }
 
-		Map<String, Object> props = new HashMap<String, Object>();
-		props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
-		Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(parentNode, propertyData, GraphEdgeLabels.HEAT_PARAMETER, props);
-		if (createRelResult.isRight()) {
-			TitanOperationStatus operationStatus = createRelResult.right().value();
-			log.error("Failed to associate {} {} to heat parameter {} in graph. status is {}", nodeType.getName(), parentId, propertyName, operationStatus);
-			return Either.right(operationStatus);
-		}
+        Map<String, Object> props = new HashMap<>();
+        props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
+        Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(parentNode, propertyData, GraphEdgeLabels.HEAT_PARAMETER, props);
+        if (createRelResult.isRight()) {
+            TitanOperationStatus operationStatus = createRelResult.right().value();
+            log.error("Failed to associate {} {} to heat parameter {} in graph. status is {}", nodeType.getName(), parentId, propertyName, operationStatus);
+            return Either.right(operationStatus);
+        }
 
-		return Either.left(createNodeResult.left().value());
+        return Either.left(createNodeResult.left().value());
 
-	}
+    }
 
-	public StorageOperationStatus validateAndUpdateProperty(HeatParameterDefinition propertyDefinition) {
+    public StorageOperationStatus validateAndUpdateProperty(HeatParameterDefinition propertyDefinition) {
+
+        log.trace("Going to validate property type and value. {}" , propertyDefinition);
 
-		log.trace("Going to validate property type and value. {}" , propertyDefinition);
+        String propertyType = propertyDefinition.getType();
+        HeatParameterType type = getType(propertyType);
 
-		String propertyType = propertyDefinition.getType();
-		HeatParameterType type = getType(propertyType);
+        if (type == null) {
+            log.info("The type {} of heat parameter is invalid", type);
 
-		if (type == null) {
-			log.info("The type {} of heat parameter is invalid", type);
+            return StorageOperationStatus.INVALID_TYPE;
+        }
+        propertyDefinition.setType(type.getType());
 
-			return StorageOperationStatus.INVALID_TYPE;
-		}
-		propertyDefinition.setType(type.getType());
+        log.trace("After validating property type {}", propertyType);
 
-		log.trace("After validating property type {}", propertyType);
+        // validate default value
+        String defaultValue = propertyDefinition.getDefaultValue();
+        boolean isValidProperty = isValidValue(type, defaultValue);
+        if (!isValidProperty) {
+            log.info("The value {} of property from type {} is invalid", defaultValue, type);
+            return StorageOperationStatus.INVALID_VALUE;
+        }
 
-		// validate default value
-		String defaultValue = propertyDefinition.getDefaultValue();
-		boolean isValidProperty = isValidValue(type, defaultValue);
-		if (false == isValidProperty) {
-			log.info("The value {} of property from type {} is invalid", defaultValue, type);
-			return StorageOperationStatus.INVALID_VALUE;
-		}
+        PropertyValueConverter converter = type.getConverter();
 
-		PropertyValueConverter converter = type.getConverter();
+        if (isEmptyValue(defaultValue)) {
+            log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName() , EMPTY_VALUE);
 
-		if (isEmptyValue(defaultValue)) {
-			log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName() , EMPTY_VALUE);
-					
-			propertyDefinition.setDefaultValue(EMPTY_VALUE);
-		} else if (false == isEmptyValue(defaultValue)) {
-			String convertedValue = converter.convert(defaultValue, null, null);
-			propertyDefinition.setDefaultValue(convertedValue);
-		}
+            propertyDefinition.setDefaultValue(EMPTY_VALUE);
+        } else if (!isEmptyValue(defaultValue)) {
+            String convertedValue = converter.convert(defaultValue, null, null);
+            propertyDefinition.setDefaultValue(convertedValue);
+        }
 
-		// validate current value
-		String value = propertyDefinition.getCurrentValue();
-		isValidProperty = isValidValue(type, value);
-		if (false == isValidProperty) {
-			log.info("The value {} of property from type {} is invalid", value, type);
-			return StorageOperationStatus.INVALID_VALUE;
-		}
+        // validate current value
+        String value = propertyDefinition.getCurrentValue();
+        isValidProperty = isValidValue(type, value);
+        if (!isValidProperty) {
+            log.info("The value {} of property from type {} is invalid", value, type);
+            return StorageOperationStatus.INVALID_VALUE;
+        }
 
-		if (isEmptyValue(value)) {
-			log.debug("Value was not sent for property {}. Set value to {}", propertyDefinition.getName(), EMPTY_VALUE);
-					
-			propertyDefinition.setCurrentValue(EMPTY_VALUE);
-		} else if (!value.equals("")) {
-			String convertedValue = converter.convert(value, null, null);
-			propertyDefinition.setCurrentValue(convertedValue);
-		}
+        if (isEmptyValue(value)) {
+            log.debug("Value was not sent for property {}. Set value to {}", propertyDefinition.getName(), EMPTY_VALUE);
 
-		return StorageOperationStatus.OK;
-	}
+            propertyDefinition.setCurrentValue(EMPTY_VALUE);
+        } else if (!value.equals("")) {
+            String convertedValue = converter.convert(value, null, null);
+            propertyDefinition.setCurrentValue(convertedValue);
+        }
 
-	public HeatParameterDefinition convertParameterDataToParameterDefinition(HeatParameterData propertyDataResult, String propertyName, String resourceId) {
-		log.debug("convert to HeatParamereDefinition {}", propertyDataResult);
+        return StorageOperationStatus.OK;
+    }
 
-		HeatParameterDefinition propertyDefResult = new HeatParameterDefinition(propertyDataResult.getHeatDataDefinition());
+    public HeatParameterDefinition convertParameterDataToParameterDefinition(HeatParameterData propertyDataResult, String propertyName, String resourceId) {
+        log.debug("convert to HeatParamereDefinition {}", propertyDataResult);
 
-		propertyDefResult.setName(propertyName);
+        HeatParameterDefinition propertyDefResult = new HeatParameterDefinition(propertyDataResult.getHeatDataDefinition());
 
-		return propertyDefResult;
-	}
+        propertyDefResult.setName(propertyName);
 
-	private HeatParameterType getType(String propertyType) {
+        return propertyDefResult;
+    }
 
-		HeatParameterType type = HeatParameterType.isValidType(propertyType);
+    private HeatParameterType getType(String propertyType) {
 
-		return type;
+        return HeatParameterType.isValidType(propertyType);
 
-	}
+    }
 
-	protected boolean isValidValue(HeatParameterType type, String value) {
-		if (isEmptyValue(value)) {
-			return true;
-		}
+    protected boolean isValidValue(HeatParameterType type, String value) {
+        if (isEmptyValue(value)) {
+            return true;
+        }
 
-		PropertyTypeValidator validator = type.getValidator();
+        PropertyTypeValidator validator = type.getValidator();
 
-		boolean isValid = validator.isValid(value, null, null);
-		if (true == isValid) {
-			return true;
-		} else {
-			return false;
-		}
+        boolean isValid = validator.isValid(value, null, null);
+        if (isValid) {
+            return true;
+        } else {
+            return false;
+        }
 
-	}
+    }
 
-	public boolean isEmptyValue(String value) {
-		if (value == null) {
-			return true;
-		}
-		return false;
-	}
+    public boolean isEmptyValue(String value) {
+        if (value == null) {
+            return true;
+        }
+        return false;
+    }
 
-	public boolean isNullParam(String value) {
-		if (value == null) {
-			return true;
-		}
-		return false;
-	}
+    public boolean isNullParam(String value) {
+        if (value == null) {
+            return true;
+        }
+        return false;
+    }
 
-	@Override
-	public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel) {
-		String heatEnvId = UniqueIdBuilder.buildHeatParameterValueUniqueId(resourceInstanceId, artifactLabel, heatParam.getName());
-		Either<HeatParameterValueData, TitanOperationStatus> getNode = titanGenericDao.getNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), heatEnvId, HeatParameterValueData.class);
-		if (getNode.isRight() || getNode.left().value() == null) {
-			if (heatParam.getCurrentValue() == null || (heatParam.getDefaultValue() != null && heatParam.getCurrentValue().equals(heatParam.getDefaultValue()))) {
-				log.debug("Updated heat parameter value equals default value. No need to create heat parameter value for heat parameter {}", heatParam.getUniqueId());
-				return Either.left(null);
-			}
-			return createHeatParameterValue(heatParam, artifactId, resourceInstanceId, artifactLabel);
-		} else {
-			heatParam.setUniqueId(heatEnvId);
-			return updateHeatParameterValue(heatParam);
-		}
-	}
+    @Override
+    public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel) {
+        String heatEnvId = UniqueIdBuilder.buildHeatParameterValueUniqueId(resourceInstanceId, artifactLabel, heatParam.getName());
+        Either<HeatParameterValueData, TitanOperationStatus> getNode = titanGenericDao.getNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), heatEnvId, HeatParameterValueData.class);
+        if (getNode.isRight() || getNode.left().value() == null) {
+            if (heatParam.getCurrentValue() == null || (heatParam.getDefaultValue() != null && heatParam.getCurrentValue().equals(heatParam.getDefaultValue()))) {
+                log.debug("Updated heat parameter value equals default value. No need to create heat parameter value for heat parameter {}", heatParam.getUniqueId());
+                return Either.left(null);
+            }
+            return createHeatParameterValue(heatParam, artifactId, resourceInstanceId, artifactLabel);
+        } else {
+            heatParam.setUniqueId(heatEnvId);
+            return updateHeatParameterValue(heatParam);
+        }
+    }
 
-	public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam) {
-		HeatParameterValueData heatParameterValue = new HeatParameterValueData();
-		heatParameterValue.setUniqueId(heatParam.getUniqueId());
-		if (heatParam.getCurrentValue() == null || (heatParam.getDefaultValue() != null && heatParam.getCurrentValue().equals(heatParam.getDefaultValue()))) {
-			Either<GraphRelation, TitanOperationStatus> deleteParameterValueIncomingRelation = titanGenericDao.deleteIncomingRelationByCriteria(heatParameterValue, GraphEdgeLabels.PARAMETER_VALUE, null);
-			if (deleteParameterValueIncomingRelation.isRight()) {
-				log.debug("Failed to delete heat parameter value incoming relation on graph. id = {}", heatParameterValue.getUniqueId());
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteParameterValueIncomingRelation.right().value()));
-			}
-			Either<Edge, TitanOperationStatus> getOutgoingRelation = titanGenericDao.getOutgoingEdgeByCriteria(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) heatParameterValue.getUniqueId(), GraphEdgeLabels.PARAMETER_IMPL, null);
-			if (getOutgoingRelation.isRight()) {
-				log.debug("Failed to get heat parameter value outgoing relation from graph. id = {}", heatParameterValue.getUniqueId());
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getOutgoingRelation.right().value()));
-			}
-			Edge edge = getOutgoingRelation.left().value();
-			if (edge == null) {
-				log.debug("Failed to get heat parameter value outgoing relation from graph. id = {}", heatParameterValue.getUniqueId());
-				return Either.right(StorageOperationStatus.GENERAL_ERROR);
-			}
-			edge.remove();
+    public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam) {
+        HeatParameterValueData heatParameterValue = new HeatParameterValueData();
+        heatParameterValue.setUniqueId(heatParam.getUniqueId());
+        if (heatParam.getCurrentValue() == null || (heatParam.getDefaultValue() != null && heatParam.getCurrentValue().equals(heatParam.getDefaultValue()))) {
+            Either<GraphRelation, TitanOperationStatus> deleteParameterValueIncomingRelation = titanGenericDao.deleteIncomingRelationByCriteria(heatParameterValue, GraphEdgeLabels.PARAMETER_VALUE, null);
+            if (deleteParameterValueIncomingRelation.isRight()) {
+                log.debug("Failed to delete heat parameter value incoming relation on graph. id = {}", heatParameterValue.getUniqueId());
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteParameterValueIncomingRelation.right().value()));
+            }
+            Either<Edge, TitanOperationStatus> getOutgoingRelation = titanGenericDao.getOutgoingEdgeByCriteria(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) heatParameterValue.getUniqueId(), GraphEdgeLabels.PARAMETER_IMPL, null);
+            if (getOutgoingRelation.isRight()) {
+                log.debug("Failed to get heat parameter value outgoing relation from graph. id = {}", heatParameterValue.getUniqueId());
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getOutgoingRelation.right().value()));
+            }
+            Edge edge = getOutgoingRelation.left().value();
+            if (edge == null) {
+                log.debug("Failed to get heat parameter value outgoing relation from graph. id = {}", heatParameterValue.getUniqueId());
+                return Either.right(StorageOperationStatus.GENERAL_ERROR);
+            }
+            edge.remove();
 
-			Either<HeatParameterValueData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(heatParameterValue, HeatParameterValueData.class);
-			if (deleteNode.isRight()) {
-				log.debug("Failed to delete heat parameter value on graph. id = {}", heatParameterValue.getUniqueId());
-				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNode.right().value()));
-			}
-			return Either.left(deleteNode.left().value());
-		}
-		heatParameterValue.setValue(heatParam.getCurrentValue());
-		Either<HeatParameterValueData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(heatParameterValue, HeatParameterValueData.class);
-		if (updateNode.isRight()) {
-			log.debug("Failed to update heat parameter value in graph. id = {}", heatParameterValue.getUniqueId());
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value()));
-		}
-		return Either.left(updateNode.left().value());
-	}
+            Either<HeatParameterValueData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(heatParameterValue, HeatParameterValueData.class);
+            if (deleteNode.isRight()) {
+                log.debug("Failed to delete heat parameter value on graph. id = {}", heatParameterValue.getUniqueId());
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNode.right().value()));
+            }
+            return Either.left(deleteNode.left().value());
+        }
+        heatParameterValue.setValue(heatParam.getCurrentValue());
+        Either<HeatParameterValueData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(heatParameterValue, HeatParameterValueData.class);
+        if (updateNode.isRight()) {
+            log.debug("Failed to update heat parameter value in graph. id = {}", heatParameterValue.getUniqueId());
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value()));
+        }
+        return Either.left(updateNode.left().value());
+    }
 
-	public Either<HeatParameterValueData, StorageOperationStatus> createHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel) {
+    public Either<HeatParameterValueData, StorageOperationStatus> createHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel) {
 
-		Either<HeatParameterValueData, TitanOperationStatus> addHeatValueToGraph = addHeatValueToGraph(heatParam, artifactLabel, artifactId, resourceInstanceId);
-		if (addHeatValueToGraph.isRight()) {
-			log.debug("Failed to create heat parameters value on graph for artifact {}", artifactId);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addHeatValueToGraph.right().value()));
-		}
-		return Either.left(addHeatValueToGraph.left().value());
-	}
+        Either<HeatParameterValueData, TitanOperationStatus> addHeatValueToGraph = addHeatValueToGraph(heatParam, artifactLabel, artifactId, resourceInstanceId);
+        if (addHeatValueToGraph.isRight()) {
+            log.debug("Failed to create heat parameters value on graph for artifact {}", artifactId);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addHeatValueToGraph.right().value()));
+        }
+        return Either.left(addHeatValueToGraph.left().value());
+    }
 
-	public Either<HeatParameterValueData, TitanOperationStatus> addHeatValueToGraph(HeatParameterDefinition heatParameter, String artifactLabel, String artifactId, String resourceInstanceId) {
+    public Either<HeatParameterValueData, TitanOperationStatus> addHeatValueToGraph(HeatParameterDefinition heatParameter, String artifactLabel, String artifactId, String resourceInstanceId) {
 
-		UniqueIdData heatEnvNode = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId);
-		HeatParameterValueData heatValueData = new HeatParameterValueData();
-		heatValueData.setUniqueId(UniqueIdBuilder.buildHeatParameterValueUniqueId(resourceInstanceId, artifactLabel, heatParameter.getName()));
-		heatValueData.setValue(heatParameter.getCurrentValue());
+        UniqueIdData heatEnvNode = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId);
+        HeatParameterValueData heatValueData = new HeatParameterValueData();
+        heatValueData.setUniqueId(UniqueIdBuilder.buildHeatParameterValueUniqueId(resourceInstanceId, artifactLabel, heatParameter.getName()));
+        heatValueData.setValue(heatParameter.getCurrentValue());
 
-		log.debug("Before adding property to graph {}", heatValueData);
-		Either<HeatParameterValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(heatValueData, HeatParameterValueData.class);
-		log.debug("After adding property to graph {}", heatValueData);
-		if (createNodeResult.isRight()) {
-			TitanOperationStatus operationStatus = createNodeResult.right().value();
-			log.error("Failed to add heat value {} to graph. status is {}", heatValueData.getUniqueId(), operationStatus);
-			return Either.right(operationStatus);
-		}
+        log.debug("Before adding property to graph {}", heatValueData);
+        Either<HeatParameterValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(heatValueData, HeatParameterValueData.class);
+        log.debug("After adding property to graph {}", heatValueData);
+        if (createNodeResult.isRight()) {
+            TitanOperationStatus operationStatus = createNodeResult.right().value();
+            log.error("Failed to add heat value {} to graph. status is {}", heatValueData.getUniqueId(), operationStatus);
+            return Either.right(operationStatus);
+        }
 
-		Map<String, Object> props = new HashMap<String, Object>();
-		props.put(GraphPropertiesDictionary.NAME.getProperty(), heatParameter.getName());
-		Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(heatEnvNode, heatValueData, GraphEdgeLabels.PARAMETER_VALUE, props);
-		if (createRelResult.isRight()) {
-			TitanOperationStatus operationStatus = createRelResult.right().value();
-			log.error("Failed to associate heat value {} to heat env artifact {} in graph. status is {}", heatValueData.getUniqueId(), artifactId, operationStatus);
-			return Either.right(operationStatus);
-		}
-		UniqueIdData heatParameterNode = new UniqueIdData(NodeTypeEnum.HeatParameter, heatParameter.getUniqueId());
-		Either<GraphRelation, TitanOperationStatus> createRel2Result = titanGenericDao.createRelation(heatValueData, heatParameterNode, GraphEdgeLabels.PARAMETER_IMPL, null);
-		if (createRel2Result.isRight()) {
-			TitanOperationStatus operationStatus = createRel2Result.right().value();
-			log.error("Failed to associate heat value {} to heat parameter {} in graph. status is {}", heatValueData.getUniqueId(), heatParameter.getName(), operationStatus);
-			return Either.right(operationStatus);
-		}
+        Map<String, Object> props = new HashMap<>();
+        props.put(GraphPropertiesDictionary.NAME.getProperty(), heatParameter.getName());
+        Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(heatEnvNode, heatValueData, GraphEdgeLabels.PARAMETER_VALUE, props);
+        if (createRelResult.isRight()) {
+            TitanOperationStatus operationStatus = createRelResult.right().value();
+            log.error("Failed to associate heat value {} to heat env artifact {} in graph. status is {}", heatValueData.getUniqueId(), artifactId, operationStatus);
+            return Either.right(operationStatus);
+        }
+        UniqueIdData heatParameterNode = new UniqueIdData(NodeTypeEnum.HeatParameter, heatParameter.getUniqueId());
+        Either<GraphRelation, TitanOperationStatus> createRel2Result = titanGenericDao.createRelation(heatValueData, heatParameterNode, GraphEdgeLabels.PARAMETER_IMPL, null);
+        if (createRel2Result.isRight()) {
+            TitanOperationStatus operationStatus = createRel2Result.right().value();
+            log.error("Failed to associate heat value {} to heat parameter {} in graph. status is {}", heatValueData.getUniqueId(), heatParameter.getName(), operationStatus);
+            return Either.right(operationStatus);
+        }
 
-		return Either.left(createNodeResult.left().value());
+        return Either.left(createNodeResult.left().value());
 
-	}
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java
index 287a63e..9c5445a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java
@@ -20,9 +20,7 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.ArrayList;
-import java.util.List;
-
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
@@ -35,205 +33,185 @@
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.ComponentInstanceInput;
 import org.openecomp.sdc.be.model.operations.api.IInputsOperation;
-import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
-import org.openecomp.sdc.be.resources.data.InputValueData;
-import org.openecomp.sdc.be.resources.data.InputsData;
-import org.openecomp.sdc.be.resources.data.PropertyData;
-import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.be.resources.data.*;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import com.google.gson.Gson;
-
-import fj.data.Either;
+import java.util.ArrayList;
+import java.util.List;
 
 @Component("input-operation")
 public class InputsOperation extends AbstractOperation implements IInputsOperation {
 
-	private static Logger log = LoggerFactory.getLogger(InputsOperation.class.getName());
-	@Autowired
-	PropertyOperation propertyOperation;
+    private static final Logger log = Logger.getLogger(InputsOperation.class.getName());
+    @Autowired
+    PropertyOperation propertyOperation;
 
-	Gson gson = new Gson();
+    public <ElementDefinition> TitanOperationStatus findAllResourceElementsDefinitionRecursively(String resourceId, List<ElementDefinition> elements, NodeElementFetcher<ElementDefinition> singleNodeFetcher) {
+
+        log.trace("Going to fetch elements under resource {}" , resourceId);
+        TitanOperationStatus resourceAttributesStatus = singleNodeFetcher.findAllNodeElements(resourceId, elements);
+
+        if (resourceAttributesStatus != TitanOperationStatus.OK) {
+            return resourceAttributesStatus;
+        }
+
+        Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class);
+
+        if (parentNodes.isRight()) {
+            TitanOperationStatus parentNodesStatus = parentNodes.right().value();
+            if (parentNodesStatus != TitanOperationStatus.NOT_FOUND) {
+                BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find parent elements of resource " + resourceId + ". status is " + parentNodesStatus, ErrorSeverity.ERROR);
+                return parentNodesStatus;
+            }
+        }
+
+        if (parentNodes.isLeft()) {
+            ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
+            String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
+            TitanOperationStatus addParentIntStatus = findAllResourceElementsDefinitionRecursively(parentUniqueId, elements, singleNodeFetcher);
+
+            if (addParentIntStatus != TitanOperationStatus.OK) {
+                BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find all resource elements of resource " + parentUniqueId, ErrorSeverity.ERROR);
+
+                return addParentIntStatus;
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
 
-	public <ElementDefinition> TitanOperationStatus findAllResourceElementsDefinitionRecursively(String resourceId, List<ElementDefinition> elements, NodeElementFetcher<ElementDefinition> singleNodeFetcher) {
+    @Override
+    public ImmutablePair<TitanOperationStatus, String> findInputValue(String resourceInstanceId, String propertyId) {
 
-		log.trace("Going to fetch elements under resource {}" , resourceId);
-		TitanOperationStatus resourceAttributesStatus = singleNodeFetcher.findAllNodeElements(resourceId, elements);
+        log.debug("Going to check whether the property {} already added to resource instance {}", propertyId, resourceInstanceId);
 
-		if (resourceAttributesStatus != TitanOperationStatus.OK) {
-			return resourceAttributesStatus;
-		}
+        Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllRes = getAllInputsOfResourceInstanceOnlyInputDefId(resourceInstanceId);
+        if (getAllRes.isRight()) {
+            TitanOperationStatus status = getAllRes.right().value();
+            log.trace("After fetching all properties of resource instance {}. Status is {}" ,resourceInstanceId, status);
+            return new ImmutablePair<>(status, null);
+        }
 
-		Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class);
+        List<ComponentInstanceInput> list = getAllRes.left().value();
+        if (list != null) {
+            for (ComponentInstanceInput instanceProperty : list) {
+                String propertyUniqueId = instanceProperty.getUniqueId();
+                String valueUniqueUid = instanceProperty.getValueUniqueUid();
+                log.trace("Go over property {} under resource instance {}. valueUniqueId = {}" ,propertyUniqueId, resourceInstanceId, valueUniqueUid);
+                if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) {
+                    log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId);
+                    return new ImmutablePair<>(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid);
+                }
+            }
+        }
 
-		if (parentNodes.isRight()) {
-			TitanOperationStatus parentNodesStatus = parentNodes.right().value();
-			if (parentNodesStatus != TitanOperationStatus.NOT_FOUND) {
-				BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find parent elements of resource " + resourceId + ". status is " + parentNodesStatus, ErrorSeverity.ERROR);
-				return parentNodesStatus;
-			}
-		}
+        return new ImmutablePair<>(TitanOperationStatus.NOT_FOUND, null);
+    }
 
-		if (parentNodes.isLeft()) {
-			ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
-			String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
-			TitanOperationStatus addParentIntStatus = findAllResourceElementsDefinitionRecursively(parentUniqueId, elements, singleNodeFetcher);
+    /**
+     * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value...
+     *
+     * @param resourceInstanceUid
+     * @return
+     */
+    public Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllInputsOfResourceInstanceOnlyInputDefId(String resourceInstanceUid) {
 
-			if (addParentIntStatus != TitanOperationStatus.OK) {
-				BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find all resource elements of resource " + parentUniqueId, ErrorSeverity.ERROR);
+        return getAllInputsOfResourceInstanceOnlyInputDefId(resourceInstanceUid, NodeTypeEnum.ResourceInstance);
 
-				return addParentIntStatus;
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+    }
+
+    public Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllInputsOfResourceInstanceOnlyInputDefId(String resourceInstanceUid, NodeTypeEnum instanceNodeType) {
+
+        Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, ComponentInstanceData.class);
+
+        if (findResInstanceRes.isRight()) {
+            TitanOperationStatus status = findResInstanceRes.right().value();
+            if (status == TitanOperationStatus.NOT_FOUND) {
+                status = TitanOperationStatus.INVALID_ID;
+            }
+            return Either.right(status);
+        }
+
+        Either<List<ImmutablePair<InputValueData, GraphEdge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, GraphEdgeLabels.INPUT_VALUE, NodeTypeEnum.InputValue, InputValueData.class);
+
+        if (propertyImplNodes.isRight()) {
+            TitanOperationStatus status = propertyImplNodes.right().value();
+            return Either.right(status);
+        }
+
+        List<ImmutablePair<InputValueData, GraphEdge>> list = propertyImplNodes.left().value();
+        if (list == null || list.isEmpty()) {
+            return Either.right(TitanOperationStatus.NOT_FOUND);
+        }
+
+        List<ComponentInstanceInput> result = new ArrayList<>();
 
 
-	@Override
-	public ImmutablePair<TitanOperationStatus, String> findInputValue(String resourceInstanceId, String propertyId) {
+        for (ImmutablePair<InputValueData, GraphEdge> propertyValueDataPair : list) {
 
-		log.debug("Going to check whether the property {} already added to resource instance {}", propertyId, resourceInstanceId);
+            InputValueData propertyValueData = propertyValueDataPair.getLeft();
+            String propertyValueUid = propertyValueData.getUniqueId();
+            String value = propertyValueData.getValue();
 
-		Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllRes = getAllInputsOfResourceInstanceOnlyInputDefId(resourceInstanceId);
-		if (getAllRes.isRight()) {
-			TitanOperationStatus status = getAllRes.right().value();
-			log.trace("After fetching all properties of resource instance {}. Status is {}" ,resourceInstanceId, status);
-			return new ImmutablePair<TitanOperationStatus, String>(status, null);
-		}
+            Either<ImmutablePair<InputsData, GraphEdge>, TitanOperationStatus> inputNodes = titanGenericDao.getParentNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), propertyValueData.getUniqueId(), GraphEdgeLabels.GET_INPUT, NodeTypeEnum.Input, InputsData.class);
 
-		List<ComponentInstanceInput> list = getAllRes.left().value();
-		if (list != null) {
-			for (ComponentInstanceInput instanceProperty : list) {
-				String propertyUniqueId = instanceProperty.getUniqueId();
-				String valueUniqueUid = instanceProperty.getValueUniqueUid();
-				log.trace("Go over property {} under resource instance {}. valueUniqueId = {}" ,propertyUniqueId, resourceInstanceId, valueUniqueUid);
-				if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) {
-					log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId);
-					return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid);
-				}
-			}
-		}
+            if (inputNodes.isRight()) {
 
-		return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.NOT_FOUND, null);
-	}
+                return Either.right(inputNodes.right().value());
+            }
 
-	/**
-	 * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value...
-	 * 
-	 * @param resourceInstanceUid
-	 * @return
-	 */
-	public Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllInputsOfResourceInstanceOnlyInputDefId(String resourceInstanceUid) {
+            InputsData input = inputNodes.left().value().left;
+            String inputId = input.getPropertyDataDefinition().getUniqueId();
 
-		return getAllInputsOfResourceInstanceOnlyInputDefId(resourceInstanceUid, NodeTypeEnum.ResourceInstance);
+            Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InputValue), propertyValueUid, GraphEdgeLabels.INPUT_IMPL, NodeTypeEnum.Property, PropertyData.class);
+            if (propertyDefRes.isRight()) {
+                TitanOperationStatus status = propertyDefRes.right().value();
+                if (status == TitanOperationStatus.NOT_FOUND) {
+                    status = TitanOperationStatus.INVALID_ID;
+                }
+                return Either.right(status);
+            }
 
-	}
+            ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value();
+            PropertyData propertyData = propertyDefPair.left;
+            Either<Edge, TitanOperationStatus> inputsEges = titanGenericDao.getIncomingEdgeByCriteria(propertyData, GraphEdgeLabels.INPUT, null);
+            if (inputsEges.isRight()) {
+                TitanOperationStatus status = inputsEges.right().value();
 
-	public Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllInputsOfResourceInstanceOnlyInputDefId(String resourceInstanceUid, NodeTypeEnum instanceNodeType) {
+                return Either.right(status);
+            }
+            Edge edge = inputsEges.left().value();
+            String inputName = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.NAME.getProperty());
 
-		Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, ComponentInstanceData.class);
+            ComponentInstanceInput resourceInstanceProperty = new ComponentInstanceInput(propertyData.getPropertyDataDefinition(), inputId, value, propertyValueUid);
 
-		if (findResInstanceRes.isRight()) {
-			TitanOperationStatus status = findResInstanceRes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.INVALID_ID;
-			}
-			return Either.right(status);
-		}
+            resourceInstanceProperty.setName(inputName);
+            resourceInstanceProperty.setParentUniqueId(inputId);
+            resourceInstanceProperty.setValue(value);
+            resourceInstanceProperty.setValueUniqueUid(propertyValueData.getUniqueId());
+            resourceInstanceProperty.setType(propertyData.getPropertyDataDefinition().getType());
+            resourceInstanceProperty.setSchema(propertyData.getPropertyDataDefinition().getSchema());
+            resourceInstanceProperty.setComponentInstanceId(resourceInstanceUid);
 
-		Either<List<ImmutablePair<InputValueData, GraphEdge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, GraphEdgeLabels.INPUT_VALUE, NodeTypeEnum.InputValue, InputValueData.class);
-
-		if (propertyImplNodes.isRight()) {
-			TitanOperationStatus status = propertyImplNodes.right().value();
-			return Either.right(status);
-		}
-
-		List<ImmutablePair<InputValueData, GraphEdge>> list = propertyImplNodes.left().value();
-		if (list == null || true == list.isEmpty()) {
-			return Either.right(TitanOperationStatus.NOT_FOUND);
-		}
-
-		List<ComponentInstanceInput> result = new ArrayList<>();
-	
-		
-		for (ImmutablePair<InputValueData, GraphEdge> propertyValueDataPair : list) {
-			
-			InputValueData propertyValueData = propertyValueDataPair.getLeft();
-			String propertyValueUid = propertyValueData.getUniqueId();
-			String value = propertyValueData.getValue();
-
-			Either<ImmutablePair<InputsData, GraphEdge>, TitanOperationStatus> inputNodes = titanGenericDao.getParentNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), propertyValueData.getUniqueId(), GraphEdgeLabels.GET_INPUT, NodeTypeEnum.Input, InputsData.class);
-
-			if (inputNodes.isRight()) {
-
-				return Either.right(inputNodes.right().value());
-			}
-
-			InputsData input = inputNodes.left().value().left;
-			String inputId = input.getPropertyDataDefinition().getUniqueId();
-
-			Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InputValue), propertyValueUid, GraphEdgeLabels.INPUT_IMPL, NodeTypeEnum.Property, PropertyData.class);
-			if (propertyDefRes.isRight()) {
-				TitanOperationStatus status = propertyDefRes.right().value();
-				if (status == TitanOperationStatus.NOT_FOUND) {
-					status = TitanOperationStatus.INVALID_ID;
-				}
-				return Either.right(status);
-			}
-
-			ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value();
-			PropertyData propertyData = propertyDefPair.left;
-			Either<Edge, TitanOperationStatus> inputsEges = titanGenericDao.getIncomingEdgeByCriteria(propertyData, GraphEdgeLabels.INPUT, null);
-			if (inputsEges.isRight()) {
-				TitanOperationStatus status = inputsEges.right().value();
-
-				return Either.right(status);
-			}
-			Edge edge = inputsEges.left().value();
-			String inputName = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.NAME.getProperty());
-
-			String propertyUniqueId = (String) propertyData.getPropertyDataDefinition().getUniqueId();
-			
-
-			ComponentInstanceInput resourceInstanceProperty = new ComponentInstanceInput(propertyData.getPropertyDataDefinition(), inputId, value, propertyValueUid);
-			
-			//resourceInstanceProperty.setName(inputName);
-			// set resource id
-			// TODO: esofer add resource id
-			resourceInstanceProperty.setName(inputName);
-			resourceInstanceProperty.setParentUniqueId(inputId);
-			// set value
-			resourceInstanceProperty.setValue(value);
-			// set property value unique id
-			resourceInstanceProperty.setValueUniqueUid(propertyValueData.getUniqueId());
-			// set rules
-			// resourceInstanceProperty.setRules(propertyValueData.getRules());
-			resourceInstanceProperty.setType(propertyData.getPropertyDataDefinition().getType());
-			resourceInstanceProperty.setSchema(propertyData.getPropertyDataDefinition().getSchema());
-			//resourceInstanceProperty.setComponentInstanceName(componentInsName);
-			resourceInstanceProperty.setComponentInstanceId(resourceInstanceUid);
-
-			result.add(resourceInstanceProperty);
-		}
+            result.add(resourceInstanceProperty);
+        }
 
 
-		return Either.left(result);
-	}
+        return Either.left(result);
+    }
 
-	@Override
-	public ComponentInstanceInput buildResourceInstanceInput(InputValueData propertyValueData, ComponentInstanceInput resourceInstanceInput) {
+    @Override
+    public ComponentInstanceInput buildResourceInstanceInput(InputValueData propertyValueData, ComponentInstanceInput resourceInstanceInput) {
 
-		String value = propertyValueData.getValue();
-		String uid = propertyValueData.getUniqueId();
-		ComponentInstanceInput instanceProperty = new ComponentInstanceInput(resourceInstanceInput, value, uid);
-		instanceProperty.setPath(resourceInstanceInput.getPath());
+        String value = propertyValueData.getValue();
+        String uid = propertyValueData.getUniqueId();
+        ComponentInstanceInput instanceProperty = new ComponentInstanceInput(resourceInstanceInput, value, uid);
+        instanceProperty.setPath(resourceInstanceInput.getPath());
 
-		return instanceProperty;
-	}
+        return instanceProperty;
+    }
 
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java
index c86559b..3482a25 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java
@@ -40,12 +40,11 @@
 import org.openecomp.sdc.be.resources.data.InterfaceData;
 import org.openecomp.sdc.be.resources.data.OperationData;
 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
-import java.util.HashMap;
-import java.util.Iterator;
+import java.util.*;
+import java.util.Map.Entry;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -54,847 +53,842 @@
 @Component("interface-operation")
 public class InterfaceLifecycleOperation implements IInterfaceLifecycleOperation {
 
-	private static Logger log = LoggerFactory.getLogger(InterfaceLifecycleOperation.class.getName());
+    private static final Logger log = Logger.getLogger(InterfaceLifecycleOperation.class.getName());
 
-	public InterfaceLifecycleOperation() {
-		super();
-	}
+    public InterfaceLifecycleOperation() {
+        super();
+    }
 
-	@javax.annotation.Resource
-	private ArtifactOperation artifactOperation;
+    @javax.annotation.Resource
+    private ArtifactOperation artifactOperation;
 
-	@javax.annotation.Resource
-	private TitanGenericDao titanGenericDao;
+    @javax.annotation.Resource
+    private TitanGenericDao titanGenericDao;
 
-	@Override
-	public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToResource(InterfaceDefinition interf, String resourceId, String interfaceName, boolean inTransaction) {
+    @Override
+    public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToResource(InterfaceDefinition interf, String resourceId, String interfaceName, boolean inTransaction) {
 
-		return createInterfaceOnResource(interf, resourceId, interfaceName, true, inTransaction);
+        return createInterfaceOnResource(interf, resourceId, interfaceName, true, inTransaction);
 
-	}
+    }
 
-	private Either<OperationData, TitanOperationStatus> addOperationToGraph(InterfaceDefinition interf, String opName, Operation op, InterfaceData interfaceData) {
+    private Either<OperationData, TitanOperationStatus> addOperationToGraph(InterfaceDefinition interf, String opName, Operation op, InterfaceData interfaceData) {
 
-		op.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId((String) interfaceData.getUniqueId(), opName));
-		OperationData operationData = new OperationData(op);
+        op.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId((String) interfaceData.getUniqueId(), opName));
+        OperationData operationData = new OperationData(op);
 
-		log.debug("Before adding operation to graph {}", operationData);
-		Either<OperationData, TitanOperationStatus> createOpNodeResult = titanGenericDao.createNode(operationData, OperationData.class);
-		log.debug("After adding operation to graph {}", operationData);
+        log.debug("Before adding operation to graph {}", operationData);
+        Either<OperationData, TitanOperationStatus> createOpNodeResult = titanGenericDao.createNode(operationData, OperationData.class);
+        log.debug("After adding operation to graph {}", operationData);
 
-		if (createOpNodeResult.isRight()) {
-			TitanOperationStatus opStatus = createOpNodeResult.right().value();
-			log.error("Failed to add operation {} to graph. status is {}", opName, opStatus);
-			return Either.right(opStatus);
-		}
+        if (createOpNodeResult.isRight()) {
+            TitanOperationStatus opStatus = createOpNodeResult.right().value();
+            log.error("Failed to add operation {} to graph. status is {}", opName, opStatus);
+            return Either.right(opStatus);
+        }
 
-		Map<String, Object> props = new HashMap<String, Object>();
-		props.put(GraphPropertiesDictionary.NAME.getProperty(), opName);
-		Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(interfaceData, operationData, GraphEdgeLabels.INTERFACE_OPERATION, props);
+        Map<String, Object> props = new HashMap<>();
+        props.put(GraphPropertiesDictionary.NAME.getProperty(), opName);
+        Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(interfaceData, operationData, GraphEdgeLabels.INTERFACE_OPERATION, props);
 
-		if (createRelResult.isRight()) {
-			TitanOperationStatus operationStatus = createOpNodeResult.right().value();
-			log.error("Failed to associate operation {} to property {} in graph. status is {}", interfaceData.getUniqueId(), opName, operationStatus);
+        if (createRelResult.isRight()) {
+            TitanOperationStatus operationStatus = createOpNodeResult.right().value();
+            log.error("Failed to associate operation {} to property {} in graph. status is {}", interfaceData.getUniqueId(), opName, operationStatus);
 
-			return Either.right(operationStatus);
-		}
+            return Either.right(operationStatus);
+        }
 
-		return Either.left(createOpNodeResult.left().value());
+        return Either.left(createOpNodeResult.left().value());
 
-	}
+    }
 
-	private InterfaceDefinition convertInterfaceDataToInterfaceDefinition(InterfaceData interfaceData) {
+    private InterfaceDefinition convertInterfaceDataToInterfaceDefinition(InterfaceData interfaceData) {
 
-		log.debug("The object returned after create interface is {}", interfaceData);
+        log.debug("The object returned after create interface is {}", interfaceData);
 
-		InterfaceDefinition interfaceDefResult = new InterfaceDefinition(interfaceData.getInterfaceDataDefinition());
+        return new InterfaceDefinition(interfaceData.getInterfaceDataDefinition());
 
-		return interfaceDefResult;
+    }
 
-	}
+    private Operation convertOperationDataToOperation(OperationData operationData) {
 
-	private Operation convertOperationDataToOperation(OperationData operationData) {
+        log.debug("The object returned after create operation is {}", operationData);
 
-		log.debug("The object returned after create operation is {}", operationData);
+        return new Operation(operationData.getOperationDataDefinition());
 
-		Operation operationDefResult = new Operation(operationData.getOperationDataDefinition());
+    }
 
-		return operationDefResult;
+    private Either<InterfaceData, TitanOperationStatus> addInterfaceToGraph(InterfaceDefinition interfaceInfo, String interfaceName, String resourceId) {
 
-	}
+        InterfaceData interfaceData = new InterfaceData(interfaceInfo);
 
-	private Either<InterfaceData, TitanOperationStatus> addInterfaceToGraph(InterfaceDefinition interfaceInfo, String interfaceName, String resourceId) {
+        ResourceMetadataData resourceData = new ResourceMetadataData();
+        resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
 
-		InterfaceData interfaceData = new InterfaceData(interfaceInfo);
+        String interfaceNameSplitted = getShortInterfaceName(interfaceInfo);
 
-		ResourceMetadataData resourceData = new ResourceMetadataData();
-		resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
+        interfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted));
 
-		String interfaceNameSplitted = getShortInterfaceName(interfaceInfo);
+        Either<InterfaceData, TitanOperationStatus> existInterface = titanGenericDao.getNode(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId(), InterfaceData.class);
 
-		interfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted));
+        if (existInterface.isRight()) {
 
-		Either<InterfaceData, TitanOperationStatus> existInterface = titanGenericDao.getNode(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId(), InterfaceData.class);
+            return createInterfaceNodeAndRelation(interfaceNameSplitted, resourceId, interfaceData, resourceData);
+        } else {
+            log.debug("Interface {} already exist", interfaceData.getUniqueId());
+            return Either.right(TitanOperationStatus.ALREADY_EXIST);
+        }
+    }
 
-		if (existInterface.isRight()) {
+    private Either<InterfaceData, TitanOperationStatus> createInterfaceNodeAndRelation(String interfaceName, String resourceId, InterfaceData interfaceData, ResourceMetadataData resourceData) {
+        log.debug("Before adding interface to graph {}", interfaceData);
+        Either<InterfaceData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(interfaceData, InterfaceData.class);
+        log.debug("After adding property to graph {}", interfaceData);
 
-			return createInterfaceNodeAndRelation(interfaceNameSplitted, resourceId, interfaceData, resourceData);
-		} else {
-			log.debug("Interface {} already exist", interfaceData.getUniqueId());
-			return Either.right(TitanOperationStatus.ALREADY_EXIST);
-		}
-	}
+        if (createNodeResult.isRight()) {
+            TitanOperationStatus operationStatus = createNodeResult.right().value();
+            log.error("Failed to add interface {} to graph. status is {}", interfaceName, operationStatus);
+            return Either.right(operationStatus);
+        }
 
-	private Either<InterfaceData, TitanOperationStatus> createInterfaceNodeAndRelation(String interfaceName, String resourceId, InterfaceData interfaceData, ResourceMetadataData resourceData) {
-		log.debug("Before adding interface to graph {}", interfaceData);
-		Either<InterfaceData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(interfaceData, InterfaceData.class);
-		log.debug("After adding property to graph {}", interfaceData);
+        Map<String, Object> props = new HashMap<>();
+        props.put(GraphPropertiesDictionary.NAME.getProperty(), interfaceName);
+        Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData, interfaceData, GraphEdgeLabels.INTERFACE, props);
+        if (createRelResult.isRight()) {
+            TitanOperationStatus operationStatus = createNodeResult.right().value();
+            log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, interfaceName, operationStatus);
 
-		if (createNodeResult.isRight()) {
-			TitanOperationStatus operationStatus = createNodeResult.right().value();
-			log.error("Failed to add interface {} to graph. status is {}", interfaceName, operationStatus);
-			return Either.right(operationStatus);
-		}
+            return Either.right(operationStatus);
+        }
 
-		Map<String, Object> props = new HashMap<String, Object>();
-		props.put(GraphPropertiesDictionary.NAME.getProperty(), interfaceName);
-		Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData, interfaceData, GraphEdgeLabels.INTERFACE, props);
-		if (createRelResult.isRight()) {
-			TitanOperationStatus operationStatus = createNodeResult.right().value();
-			log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, interfaceName, operationStatus);
+        return Either.left(createNodeResult.left().value());
+    }
 
-			return Either.right(operationStatus);
-		}
+    private Either<OperationData, TitanOperationStatus> createOperationNodeAndRelation(String operationName, OperationData operationData, InterfaceData interfaceData) {
+        log.debug("Before adding operation to graph {}", operationData);
+        Either<OperationData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(operationData, OperationData.class);
+        log.debug("After adding operation to graph {}", interfaceData);
 
-		return Either.left(createNodeResult.left().value());
-	}
+        if (createNodeResult.isRight()) {
+            TitanOperationStatus operationStatus = createNodeResult.right().value();
+            log.error("Failed to add interfoperationce {} to graph. status is {}", operationName, operationStatus);
+            return Either.right(operationStatus);
+        }
 
-	private Either<OperationData, TitanOperationStatus> createOperationNodeAndRelation(String operationName, OperationData operationData, InterfaceData interfaceData) {
-		log.debug("Before adding operation to graph {}", operationData);
-		Either<OperationData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(operationData, OperationData.class);
-		log.debug("After adding operation to graph {}", interfaceData);
+        Map<String, Object> props = new HashMap<>();
+        props.put(GraphPropertiesDictionary.NAME.getProperty(), operationName);
+        Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(interfaceData, operationData, GraphEdgeLabels.INTERFACE_OPERATION, props);
+        if (createRelResult.isRight()) {
+            TitanOperationStatus operationStatus = createNodeResult.right().value();
+            log.error("Failed to associate operation {} to interface {} in graph. status is {}", operationName, interfaceData.getUniqueId(), operationStatus);
 
-		if (createNodeResult.isRight()) {
-			TitanOperationStatus operationStatus = createNodeResult.right().value();
-			log.error("Failed to add interfoperationce {} to graph. status is {}", operationName, operationStatus);
-			return Either.right(operationStatus);
-		}
+            return Either.right(operationStatus);
+        }
 
-		Map<String, Object> props = new HashMap<String, Object>();
-		props.put(GraphPropertiesDictionary.NAME.getProperty(), operationName);
-		Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(interfaceData, operationData, GraphEdgeLabels.INTERFACE_OPERATION, props);
-		if (createRelResult.isRight()) {
-			TitanOperationStatus operationStatus = createNodeResult.right().value();
-			log.error("Failed to associate operation {} to interface {} in graph. status is {}", operationName, interfaceData.getUniqueId(), operationStatus);
+        return Either.left(createNodeResult.left().value());
+    }
 
-			return Either.right(operationStatus);
-		}
+    @Override
+    public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource(String resourceIdn, boolean recursively) {
+        return getAllInterfacesOfResource(resourceIdn, recursively, false);
+    }
 
-		return Either.left(createNodeResult.left().value());
-	}
+    @Override
+    public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource(String resourceId, boolean recursively, boolean inTransaction) {
 
-	@Override
-	public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource(String resourceIdn, boolean recursively) {
-		return getAllInterfacesOfResource(resourceIdn, recursively, false);
-	}
+        Either<Map<String, InterfaceDefinition>, StorageOperationStatus> result = null;
+        Map<String, InterfaceDefinition> interfaces = new HashMap<>();
+        try {
+            if ((resourceId == null) || resourceId.isEmpty()) {
+                log.error("resourceId is empty");
+                result = Either.right(StorageOperationStatus.INVALID_ID);
+                return result;
+            }
 
-	@Override
-	public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource(String resourceId, boolean recursively, boolean inTransaction) {
+            TitanOperationStatus findInterfacesRes = TitanOperationStatus.GENERAL_ERROR;
+            if (recursively) {
+                findInterfacesRes = findAllInterfacesRecursively(resourceId, interfaces);
+            } else {
+                findInterfacesRes = findAllInterfacesNotRecursively(resourceId, interfaces);
+            }
+            if (!findInterfacesRes.equals(TitanOperationStatus.OK)) {
+                log.error("Failed to get all interfaces of resource {}. status is {}", resourceId, findInterfacesRes);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findInterfacesRes));
+                return result;
+            }
+            result = Either.left(interfaces);
+            return result;
+        } finally {
+            if (!inTransaction) {
+                if (result == null || result.isRight()) {
+                    log.error("Going to execute rollback on graph.");
+                    titanGenericDao.rollback();
+                } else {
+                    log.debug("Going to execute commit on graph.");
+                    titanGenericDao.commit();
+                }
+            }
+        }
+    }
 
-		Either<Map<String, InterfaceDefinition>, StorageOperationStatus> result = null;
-		Map<String, InterfaceDefinition> interfaces = new HashMap<String, InterfaceDefinition>();
-		try {
-			if ((resourceId == null) || resourceId.isEmpty()) {
-				log.error("resourceId is empty");
-				result = Either.right(StorageOperationStatus.INVALID_ID);
-				return result;
-			}
+    private TitanOperationStatus findAllInterfacesNotRecursively(String resourceId, Map<String, InterfaceDefinition> interfaces) {
 
-			TitanOperationStatus findInterfacesRes = TitanOperationStatus.GENERAL_ERROR;
-			if (recursively) {
-				findInterfacesRes = findAllInterfacesRecursively(resourceId, interfaces);
-			} else {
-				findInterfacesRes = findAllInterfacesNotRecursively(resourceId, interfaces);
-			}
-			if (!findInterfacesRes.equals(TitanOperationStatus.OK)) {
-				log.error("Failed to get all interfaces of resource {}. status is {}", resourceId, findInterfacesRes);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findInterfacesRes));
-				return result;
-			}
-			result = Either.left(interfaces);
-			return result;
-		} finally {
-			if (false == inTransaction) {
-				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
-					titanGenericDao.rollback();
-				} else {
-					log.debug("Going to execute commit on graph.");
-					titanGenericDao.commit();
-				}
-			}
-		}
-	}
+        Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> interfaceNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.INTERFACE,
+                NodeTypeEnum.Interface, InterfaceData.class);
 
-	private TitanOperationStatus findAllInterfacesNotRecursively(String resourceId, Map<String, InterfaceDefinition> interfaces) {
+        if (interfaceNodes.isRight()) {
+            TitanOperationStatus status = interfaceNodes.right().value();
+            if (status != TitanOperationStatus.NOT_FOUND) {
+                return status;
+            }
+        } else {
+            List<ImmutablePair<InterfaceData, GraphEdge>> interfaceList = interfaceNodes.left().value();
+            if (interfaceList != null) {
+                for (ImmutablePair<InterfaceData, GraphEdge> interfacePair : interfaceList) {
+                    String interfaceUniqueId = (String) interfacePair.getKey().getUniqueId();
+                    Either<String, TitanOperationStatus> interfaceNameRes = getPropertyValueFromEdge(interfacePair.getValue(), GraphPropertiesDictionary.NAME);
+                    if (interfaceNameRes.isRight()) {
+                        log.error("The requirement name is missing on the edge of requirement {}", interfaceUniqueId);
+                        return interfaceNameRes.right().value();
+                    }
+                    String interfaceName = interfaceNameRes.left().value();
+                    Either<InterfaceDefinition, TitanOperationStatus> interfaceDefRes = getNonRecursiveInterface(interfacePair.getKey());
+                    if (interfaceDefRes.isRight()) {
+                        TitanOperationStatus status = interfaceDefRes.right().value();
+                        log.error("Failed to get interface actions of interface {}", interfaceUniqueId);
+                        return status;
+                    }
 
-		Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> interfaceNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.INTERFACE,
-				NodeTypeEnum.Interface, InterfaceData.class);
+                    InterfaceDefinition interfaceDefinition = interfaceDefRes.left().value();
+                    if (interfaces.containsKey(interfaceName)) {
+                        log.debug("The interface {} was already defined in dervied resource. add not overriden operations", interfaceName);
+                        InterfaceDefinition existInterface = interfaces.get(interfaceName);
+                        addMissingOperationsToInterface(interfaceDefinition, existInterface);
+                    } else {
+                        interfaces.put(interfaceName, interfaceDefinition);
+                    }
 
-		if (interfaceNodes.isRight()) {
-			TitanOperationStatus status = interfaceNodes.right().value();
-			if (status != TitanOperationStatus.NOT_FOUND) {
-				return status;
-			}
-		} else {
-			List<ImmutablePair<InterfaceData, GraphEdge>> interfaceList = interfaceNodes.left().value();
-			if (interfaceList != null) {
-				for (ImmutablePair<InterfaceData, GraphEdge> interfacePair : interfaceList) {
-					String interfaceUniqueId = (String) interfacePair.getKey().getUniqueId();
-					Either<String, TitanOperationStatus> interfaceNameRes = getPropertyValueFromEdge(interfacePair.getValue(), GraphPropertiesDictionary.NAME);
-					if (interfaceNameRes.isRight()) {
-						log.error("The requirement name is missing on the edge of requirement {}", interfaceUniqueId);
-						return interfaceNameRes.right().value();
-					}
-					String interfaceName = interfaceNameRes.left().value();
-					Either<InterfaceDefinition, TitanOperationStatus> interfaceDefRes = getNonRecursiveInterface(interfacePair.getKey());
-					if (interfaceDefRes.isRight()) {
-						TitanOperationStatus status = interfaceDefRes.right().value();
-						log.error("Failed to get interface actions of interface {}", interfaceUniqueId);
-						return status;
-					}
+                }
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
 
-					InterfaceDefinition interfaceDefinition = interfaceDefRes.left().value();
-					if (true == interfaces.containsKey(interfaceName)) {
-						log.debug("The interface {} was already defined in dervied resource. add not overriden operations", interfaceName);
-						InterfaceDefinition existInterface = interfaces.get(interfaceName);
-						addMissingOperationsToInterface(interfaceDefinition, existInterface);
-					} else {
-						interfaces.put(interfaceName, interfaceDefinition);
-					}
+    public TitanOperationStatus findAllInterfacesRecursively(String resourceId, Map<String, InterfaceDefinition> interfaces) {
 
-				}
-			}
-		}
-		return TitanOperationStatus.OK;
-	}
+        TitanOperationStatus findAllInterfacesNotRecursively = findAllInterfacesNotRecursively(resourceId, interfaces);
+        if (!findAllInterfacesNotRecursively.equals(TitanOperationStatus.OK)) {
+            log.error("failed to get interfaces for resource {}. status is {}", resourceId, findAllInterfacesNotRecursively);
+        }
 
-	public TitanOperationStatus findAllInterfacesRecursively(String resourceId, Map<String, InterfaceDefinition> interfaces) {
+        Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
+                ResourceMetadataData.class);
 
-		TitanOperationStatus findAllInterfacesNotRecursively = findAllInterfacesNotRecursively(resourceId, interfaces);
-		if (!findAllInterfacesNotRecursively.equals(TitanOperationStatus.OK)) {
-			log.error("failed to get interfaces for resource {}. status is {}", resourceId, findAllInterfacesNotRecursively);
-		}
+        if (parentNodes.isRight()) {
+            TitanOperationStatus parentNodesStatus = parentNodes.right().value();
+            if (parentNodesStatus == TitanOperationStatus.NOT_FOUND) {
+                log.debug("Finish to lookup for parnet interfaces");
+                return TitanOperationStatus.OK;
+            } else {
+                log.error("Failed to find parent interfaces of resource {}. status is {}", resourceId, parentNodesStatus);
+                return parentNodesStatus;
+            }
+        }
+        ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
+        String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
+        TitanOperationStatus addParentIntStatus = findAllInterfacesRecursively(parentUniqueId, interfaces);
 
-		Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
-				ResourceMetadataData.class);
+        if (addParentIntStatus != TitanOperationStatus.OK) {
+            log.error("Failed to fetch all interfaces of resource {}", parentUniqueId);
+            return addParentIntStatus;
+        }
 
-		if (parentNodes.isRight()) {
-			TitanOperationStatus parentNodesStatus = parentNodes.right().value();
-			if (parentNodesStatus == TitanOperationStatus.NOT_FOUND) {
-				log.debug("Finish to lookup for parnet interfaces");
-				return TitanOperationStatus.OK;
-			} else {
-				log.error("Failed to find parent interfaces of resource {}. status is {}", resourceId, parentNodesStatus);
-				return parentNodesStatus;
-			}
-		}
-		ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
-		String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
-		TitanOperationStatus addParentIntStatus = findAllInterfacesRecursively(parentUniqueId, interfaces);
+        return TitanOperationStatus.OK;
+    }
 
-		if (addParentIntStatus != TitanOperationStatus.OK) {
-			log.error("Failed to fetch all interfaces of resource {}", parentUniqueId);
-			return addParentIntStatus;
-		}
+    private Either<String, TitanOperationStatus> getPropertyValueFromEdge(GraphEdge edge, GraphPropertiesDictionary property) {
+        Map<String, Object> edgeProps = edge.getProperties();
+        String interfaceName = null;
+        if (edgeProps != null) {
+            interfaceName = (String) edgeProps.get(property.getProperty());
+            if (interfaceName == null) {
+                return Either.right(TitanOperationStatus.INVALID_ELEMENT);
+            }
+        } else {
+            return Either.right(TitanOperationStatus.INVALID_ELEMENT);
+        }
+        return Either.left(interfaceName);
+    }
 
-		return TitanOperationStatus.OK;
-	}
+    private Either<InterfaceDefinition, TitanOperationStatus> getNonRecursiveInterface(InterfaceData interfaceData) {
 
-	private Either<String, TitanOperationStatus> getPropertyValueFromEdge(GraphEdge edge, GraphPropertiesDictionary property) {
-		Map<String, Object> edgeProps = edge.getProperties();
-		String interfaceName = null;
-		if (edgeProps != null) {
-			interfaceName = (String) edgeProps.get(property.getProperty());
-			if (interfaceName == null) {
-				return Either.right(TitanOperationStatus.INVALID_ELEMENT);
-			}
-		} else {
-			return Either.right(TitanOperationStatus.INVALID_ELEMENT);
-		}
-		return Either.left(interfaceName);
-	}
+        log.debug("Going to fetch the operations associate to interface {}", interfaceData.getUniqueId());
+        InterfaceDefinition interfaceDefinition = new InterfaceDefinition(interfaceData.getInterfaceDataDefinition());
 
-	private Either<InterfaceDefinition, TitanOperationStatus> getNonRecursiveInterface(InterfaceData interfaceData) {
+        String interfaceId = interfaceData.getUniqueId();
+        Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationsRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), interfaceId, GraphEdgeLabels.INTERFACE_OPERATION,
+                NodeTypeEnum.InterfaceOperation, OperationData.class);
 
-		log.debug("Going to fetch the operations associate to interface {}", interfaceData.getUniqueId());
-		InterfaceDefinition interfaceDefinition = new InterfaceDefinition(interfaceData.getInterfaceDataDefinition());
+        if (operationsRes.isRight()) {
+            TitanOperationStatus status = operationsRes.right().value();
+            if (status != TitanOperationStatus.NOT_FOUND) {
+                return Either.right(status);
+            } else {
+                return Either.left(interfaceDefinition);
+            }
+        }
 
-		String interfaceId = interfaceData.getUniqueId();
-		Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationsRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), interfaceId, GraphEdgeLabels.INTERFACE_OPERATION,
-				NodeTypeEnum.InterfaceOperation, OperationData.class);
+        List<ImmutablePair<OperationData, GraphEdge>> operationList = operationsRes.left().value();
+        if (operationList != null && !operationList.isEmpty()) {
+            for (ImmutablePair<OperationData, GraphEdge> operationPair : operationList) {
+                Operation operation = new Operation(operationPair.getKey().getOperationDataDefinition());
+                Either<String, TitanOperationStatus> operationNameRes = getPropertyValueFromEdge(operationPair.getValue(), GraphPropertiesDictionary.NAME);
+                if (operationNameRes.isRight()) {
+                    log.error("The operation name is missing on the edge of operation {}", operationPair.getKey().getUniqueId());
+                    return Either.right(operationNameRes.right().value());
+                }
+                String operationName = operationNameRes.left().value();
+                findOperationImplementation(operation);
+                interfaceDefinition.getOperations().put(operationName, operation);
+            }
+        }
 
-		if (operationsRes.isRight()) {
-			TitanOperationStatus status = operationsRes.right().value();
-			if (status != TitanOperationStatus.NOT_FOUND) {
-				return Either.right(status);
-			} else {
-				return Either.left(interfaceDefinition);
-			}
-		}
+        return Either.left(interfaceDefinition);
+    }
 
-		List<ImmutablePair<OperationData, GraphEdge>> operationList = operationsRes.left().value();
-		if (operationList != null && !operationList.isEmpty()) {
-			for (ImmutablePair<OperationData, GraphEdge> operationPair : operationList) {
-				Operation operation = new Operation(operationPair.getKey().getOperationDataDefinition());
-				Either<String, TitanOperationStatus> operationNameRes = getPropertyValueFromEdge(operationPair.getValue(), GraphPropertiesDictionary.NAME);
-				if (operationNameRes.isRight()) {
-					log.error("The operation name is missing on the edge of operation {}", operationPair.getKey().getUniqueId());
-					return Either.right(operationNameRes.right().value());
-				}
-				String operationName = operationNameRes.left().value();
-				findOperationImplementation(operation);
-				interfaceDefinition.getOperations().put(operationName, operation);
-			}
-		}
+    private StorageOperationStatus findOperationImplementation(Operation operation) {
 
-		return Either.left(interfaceDefinition);
-	}
+        String operationId = operation.getUniqueId();
+        Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsRes = artifactOperation.getArtifacts(operationId, NodeTypeEnum.InterfaceOperation, true);
+        if (artifactsRes.isRight() || artifactsRes.left().value() == null) {
+            log.error("failed to get artifact from graph for operation id {}. status is {}", operationId, artifactsRes.right().value());
+            return artifactsRes.right().value();
+        } else {
+            Map<String, ArtifactDefinition> artifacts = artifactsRes.left().value();
+            Iterator<String> iter = artifacts.keySet().iterator();
 
-	private StorageOperationStatus findOperationImplementation(Operation operation) {
+            if (iter.hasNext()) {
+                operation.setImplementation(artifacts.get(iter.next()));
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-		String operationId = operation.getUniqueId();
-		Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsRes = artifactOperation.getArtifacts(operationId, NodeTypeEnum.InterfaceOperation, true);
-		if (artifactsRes.isRight() || artifactsRes.left().value() == null) {
-			log.error("failed to get artifact from graph for operation id {}. status is {}", operationId, artifactsRes.right().value());
-			return artifactsRes.right().value();
-		} else {
-			Map<String, ArtifactDefinition> artifacts = artifactsRes.left().value();
-			Iterator<String> iter = artifacts.keySet().iterator();
+    private StorageOperationStatus addMissingOperationsToInterface(InterfaceDefinition interfaceDefinition, InterfaceDefinition existInterface) {
+        Map<String, Operation> existOperations = existInterface.getOperationsMap();
+        Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
+        if (operations != null && !operations.isEmpty()) {
+            Set<Entry<String, Operation>> operationsSet = operations.entrySet();
+            for (Entry<String, Operation> operation : operationsSet) {
+                if (!existOperations.containsKey(operation.getKey())) {
+                    existOperations.put(operation.getKey(), operation.getValue());
+                }
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
 
-			if (iter.hasNext()) {
-				operation.setImplementation(artifacts.get(iter.next()));
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+    @Override
+    public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, String operationName, Operation interf) {
 
-	private StorageOperationStatus addMissingOperationsToInterface(InterfaceDefinition interfaceDefinition, InterfaceDefinition existInterface) {
-		Map<String, Operation> existOperations = existInterface.getOperationsMap();
-		Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
-		if (operations != null && !operations.isEmpty()) {
-			Set<Entry<String, Operation>> operationsSet = operations.entrySet();
-			for (Entry<String, Operation> operation : operationsSet) {
-				if (!existOperations.containsKey(operation.getKey())) {
-					existOperations.put(operation.getKey(), operation.getValue());
-				}
-			}
-		}
-		return StorageOperationStatus.OK;
-	}
+        return updateInterfaceOperation(resourceId, interfaceName, operationName, interf, false);
+    }
 
-	@Override
-	public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, String operationName, Operation interf) {
+    @Override
+    public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, String operationName, Operation operation, boolean inTransaction) {
+        return updateOperationOnGraph(operation, resourceId, interfaceName, operationName);
+    }
 
-		return updateInterfaceOperation(resourceId, interfaceName, operationName, interf, false);
-	}
+    private Either<Operation, StorageOperationStatus> updateOperationOnGraph(Operation operation, String resourceId, String interfaceName, String operationName) {
 
-	@Override
-	public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, String operationName, Operation operation, boolean inTransaction) {
-		Either<Operation, StorageOperationStatus> status = updateOperationOnGraph(operation, resourceId, interfaceName, operationName);
-		return status;
-	}
+        Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface,
+                InterfaceData.class);
 
-	private Either<Operation, StorageOperationStatus> updateOperationOnGraph(Operation operation, String resourceId, String interfaceName, String operationName) {
+        if (childrenNodes.isRight()) {
+            return updateOperationFromParentNode(operation, resourceId, interfaceName, operationName);
 
-		Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface,
-				InterfaceData.class);
+        } else {
+            return updateExistingOperation(resourceId, operation, interfaceName, operationName, childrenNodes);
 
-		if (childrenNodes.isRight()) {
-			return updateOperationFromParentNode(operation, resourceId, interfaceName, operationName);
+        }
 
-		} else {
-			return updateExistingOperation(resourceId, operation, interfaceName, operationName, childrenNodes);
+    }
 
-		}
+    private Either<Operation, StorageOperationStatus> updateExistingOperation(String resourceId, Operation operation, String interfaceName, String operationName,
+            Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes) {
+        Operation newOperation = null;
+        StorageOperationStatus storageOperationStatus = StorageOperationStatus.GENERAL_ERROR;
 
-	}
+        for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) {
 
-	private Either<Operation, StorageOperationStatus> updateExistingOperation(String resourceId, Operation operation, String interfaceName, String operationName,
-			Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes) {
-		Operation newOperation = null;
-		StorageOperationStatus storageOperationStatus = StorageOperationStatus.GENERAL_ERROR;
+            GraphEdge interfaceEdge = interfaceDataNode.getRight();
+            Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties();
+            InterfaceData interfaceData = interfaceDataNode.getKey();
 
-		for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) {
+            if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceName)) {
+                Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) interfaceDataNode.getLeft().getUniqueId(),
+                        GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
+                if (operationRes.isRight()) {
+                    log.error("Failed to find operation  {} on interface {}", operationName, interfaceName);
+                    return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
+                } else {
+                    List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value();
+                    for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) {
+                        GraphEdge opEdge = operationPairEdge.getRight();
+                        OperationData opData = operationPairEdge.getLeft();
+                        Map<String, Object> opEdgeProp = opEdge.getProperties();
+                        if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) {
+                            ArtifactDefinition artifact = operation.getImplementationArtifact();
+                            Either<ImmutablePair<ArtifactData, GraphEdge>, TitanOperationStatus> artifactRes = titanGenericDao.getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) opData.getUniqueId(), GraphEdgeLabels.ARTIFACT_REF,
+                                    NodeTypeEnum.ArtifactRef, ArtifactData.class);
+                            Either<ArtifactDefinition, StorageOperationStatus> artStatus;
+                            if (artifactRes.isRight()) {
+                                artStatus = artifactOperation.addArifactToComponent(artifact, (String) operationPairEdge.getLeft().getUniqueId(), NodeTypeEnum.InterfaceOperation, true, true);
+                            } else {
+                                artStatus = artifactOperation.updateArifactOnResource(artifact, (String) operationPairEdge.getLeft().getUniqueId(), (String) artifactRes.left().value().getLeft().getUniqueId(), NodeTypeEnum.InterfaceOperation, true);
+                            }
+                            if (artStatus.isRight()) {
+                                titanGenericDao.rollback();
+                                log.error("Failed to add artifact {} to interface {}", operationName, interfaceName);
+                                return Either.right(artStatus.right().value());
+                            } else {
+                                newOperation = this.convertOperationDataToOperation(opData);
+                                newOperation.setImplementation(artStatus.left().value());
 
-			GraphEdge interfaceEdge = interfaceDataNode.getRight();
-			Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties();
-			InterfaceData interfaceData = interfaceDataNode.getKey();
+                            }
 
-			if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceName)) {
-				Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) interfaceDataNode.getLeft().getUniqueId(),
-						GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
-				if (operationRes.isRight()) {
-					log.error("Failed to find operation  {} on interface {}", operationName, interfaceName);
-					return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
-				} else {
-					List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value();
-					for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) {
-						GraphEdge opEdge = operationPairEdge.getRight();
-						OperationData opData = operationPairEdge.getLeft();
-						Map<String, Object> opEdgeProp = opEdge.getProperties();
-						if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) {
-							ArtifactDefinition artifact = operation.getImplementationArtifact();
-							Either<ImmutablePair<ArtifactData, GraphEdge>, TitanOperationStatus> artifactRes = titanGenericDao.getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) opData.getUniqueId(), GraphEdgeLabels.ARTIFACT_REF,
-									NodeTypeEnum.ArtifactRef, ArtifactData.class);
-							Either<ArtifactDefinition, StorageOperationStatus> artStatus;
-							if (artifactRes.isRight()) {
-								artStatus = artifactOperation.addArifactToComponent(artifact, (String) operationPairEdge.getLeft().getUniqueId(), NodeTypeEnum.InterfaceOperation, true, true);
-							} else {
-								artStatus = artifactOperation.updateArifactOnResource(artifact, (String) operationPairEdge.getLeft().getUniqueId(), (String) artifactRes.left().value().getLeft().getUniqueId(), NodeTypeEnum.InterfaceOperation, true);
-							}
-							if (artStatus.isRight()) {
-								titanGenericDao.rollback();
-								log.error("Failed to add artifact {} to interface {}", operationName, interfaceName);
-								return Either.right(artStatus.right().value());
-							} else {
-								newOperation = this.convertOperationDataToOperation(opData);
-								newOperation.setImplementation(artStatus.left().value());
+                        }
 
-							}
+                    }
+                    if (newOperation == null) {
+                        Either<InterfaceData, TitanOperationStatus> parentInterfaceStatus = findInterfaceOnParentNode(resourceId, interfaceName);
+                        if (parentInterfaceStatus.isRight()) {
+                            log.debug("Interface {} not exist", interfaceName);
+                            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentInterfaceStatus.right().value()));
+                        }
 
-						}
+                        InterfaceData parentInterfaceData = parentInterfaceStatus.left().value();
+                        Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> opRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) parentInterfaceData.getUniqueId(),
+                                GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
+                        if (opRes.isRight()) {
+                            log.error("Failed to find operation  {} on interface {}", operationName, interfaceName);
+                            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
 
-					}
-					if (newOperation == null) {
-						Either<InterfaceData, TitanOperationStatus> parentInterfaceStatus = findInterfaceOnParentNode(resourceId, interfaceName);
-						if (parentInterfaceStatus.isRight()) {
-							log.debug("Interface {} not exist", interfaceName);
-							return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentInterfaceStatus.right().value()));
-						}
+                        } else {
+                            List<ImmutablePair<OperationData, GraphEdge>> parentOperations = opRes.left().value();
+                            for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : parentOperations) {
+                                GraphEdge opEdge = operationPairEdge.getRight();
+                                OperationData opData = operationPairEdge.getLeft();
+                                Map<String, Object> opEdgeProp = opEdge.getProperties();
+                                if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) {
+                                    return copyAndCreateNewOperation(operation, interfaceName, operationName, null, interfaceData, operationRes, opData);
+                                }
+                            }
+                        }
 
-						InterfaceData parentInterfaceData = parentInterfaceStatus.left().value();
-						Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> opRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) parentInterfaceData.getUniqueId(),
-								GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
-						if (opRes.isRight()) {
-							log.error("Failed to find operation  {} on interface {}", operationName, interfaceName);
-							return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
+                    }
 
-						} else {
-							List<ImmutablePair<OperationData, GraphEdge>> parentOperations = opRes.left().value();
-							for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : parentOperations) {
-								GraphEdge opEdge = operationPairEdge.getRight();
-								OperationData opData = operationPairEdge.getLeft();
-								Map<String, Object> opEdgeProp = opEdge.getProperties();
-								if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) {
-									return copyAndCreateNewOperation(operation, interfaceName, operationName, null, interfaceData, operationRes, opData);
-								}
-							}
-						}
-
-					}
-
-				}
+                }
 
-			} else {
-				// not found
-				storageOperationStatus = StorageOperationStatus.ARTIFACT_NOT_FOUND;
-			}
+            } else {
+                // not found
+                storageOperationStatus = StorageOperationStatus.ARTIFACT_NOT_FOUND;
+            }
 
-		}
-		if (newOperation == null)
-			return Either.right(storageOperationStatus);
-		else
-			return Either.left(newOperation);
-	}
+        }
+        if (newOperation == null)
+            return Either.right(storageOperationStatus);
+        else
+            return Either.left(newOperation);
+    }
 
-	private Either<Operation, StorageOperationStatus> copyAndCreateNewOperation(Operation operation, String interfaceName, String operationName, Operation newOperation, InterfaceData interfaceData,
-			Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes, OperationData opData) {
-		OperationDataDefinition opDataInfo = opData.getOperationDataDefinition();
-		OperationDataDefinition newOperationInfo = new OperationDataDefinition(opDataInfo);
-		newOperationInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(interfaceData.getUniqueId(), operationName.toLowerCase()));
-		OperationData newopData = new OperationData(newOperationInfo);
-		Either<OperationData, TitanOperationStatus> operationStatus = createOperationNodeAndRelation(operationName, newopData, interfaceData);
-		if (operationStatus.isRight()) {
-			log.error("Failed to create operation  {} on interface {}", operationName, interfaceName);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
-		}
-		ArtifactDefinition artifact = operation.getImplementationArtifact();
-		if (artifact != null) {
-			Either<ArtifactDefinition, StorageOperationStatus> artStatus = artifactOperation.addArifactToComponent(artifact, (String) operationStatus.left().value().getUniqueId(), NodeTypeEnum.InterfaceOperation, true, true);
-			if (artStatus.isRight()) {
-				titanGenericDao.rollback();
-				log.error("Failed to add artifact {} to interface {}", operationName, interfaceName);
-			} else {
-				newOperation = this.convertOperationDataToOperation(opData);
-				newOperation.setImplementation(artStatus.left().value());
+    private Either<Operation, StorageOperationStatus> copyAndCreateNewOperation(Operation operation, String interfaceName, String operationName, Operation newOperation, InterfaceData interfaceData,
+            Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes, OperationData opData) {
+        OperationDataDefinition opDataInfo = opData.getOperationDataDefinition();
+        OperationDataDefinition newOperationInfo = new OperationDataDefinition(opDataInfo);
+        newOperationInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(interfaceData.getUniqueId(), operationName.toLowerCase()));
+        OperationData newopData = new OperationData(newOperationInfo);
+        Either<OperationData, TitanOperationStatus> operationStatus = createOperationNodeAndRelation(operationName, newopData, interfaceData);
+        if (operationStatus.isRight()) {
+            log.error("Failed to create operation  {} on interface {}", operationName, interfaceName);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
+        }
+        ArtifactDefinition artifact = operation.getImplementationArtifact();
+        if (artifact != null) {
+            Either<ArtifactDefinition, StorageOperationStatus> artStatus = artifactOperation.addArifactToComponent(artifact, (String) operationStatus.left().value().getUniqueId(), NodeTypeEnum.InterfaceOperation, true, true);
+            if (artStatus.isRight()) {
+                titanGenericDao.rollback();
+                log.error("Failed to add artifact {} to interface {}", operationName, interfaceName);
+            } else {
+                newOperation = this.convertOperationDataToOperation(opData);
+                newOperation.setImplementation(artStatus.left().value());
 
-			}
-		}
-		return Either.left(newOperation);
-	}
+            }
+        }
+        return Either.left(newOperation);
+    }
 
-	private Either<Operation, StorageOperationStatus> updateOperationFromParentNode(Operation operation, String resourceId, String interfaceName, String operationName) {
-		// Operation newOperation = null;
-		ResourceMetadataData resourceData = new ResourceMetadataData();
-		resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
-		Either<InterfaceData, TitanOperationStatus> parentInterfaceStatus = findInterfaceOnParentNode(resourceId, interfaceName);
-		if (parentInterfaceStatus.isRight()) {
-			log.debug("Interface {} not exist", interfaceName);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentInterfaceStatus.right().value()));
-		}
+    private Either<Operation, StorageOperationStatus> updateOperationFromParentNode(Operation operation, String resourceId, String interfaceName, String operationName) {
+        // Operation newOperation = null;
+        ResourceMetadataData resourceData = new ResourceMetadataData();
+        resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
+        Either<InterfaceData, TitanOperationStatus> parentInterfaceStatus = findInterfaceOnParentNode(resourceId, interfaceName);
+        if (parentInterfaceStatus.isRight()) {
+            log.debug("Interface {} not exist", interfaceName);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentInterfaceStatus.right().value()));
+        }
 
-		InterfaceData interfaceData = parentInterfaceStatus.left().value();
-		InterfaceDataDefinition intDataDefinition = interfaceData.getInterfaceDataDefinition();
-		InterfaceDataDefinition newInterfaceInfo = new InterfaceDataDefinition(intDataDefinition);
+        InterfaceData interfaceData = parentInterfaceStatus.left().value();
+        InterfaceDataDefinition intDataDefinition = interfaceData.getInterfaceDataDefinition();
+        InterfaceDataDefinition newInterfaceInfo = new InterfaceDataDefinition(intDataDefinition);
 
-		String interfaceNameSplitted = getShortInterfaceName(intDataDefinition);
+        String interfaceNameSplitted = getShortInterfaceName(intDataDefinition);
 
-		newInterfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted));
-		InterfaceData updatedInterfaceData = new InterfaceData(newInterfaceInfo);
-		Either<InterfaceData, TitanOperationStatus> createStatus = createInterfaceNodeAndRelation(interfaceName, resourceId, updatedInterfaceData, resourceData);
-		if (createStatus.isRight()) {
-			log.debug("failed to create interface node  {} on resource  {}", interfaceName,  resourceId);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createStatus.right().value()));
-		}
+        newInterfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted));
+        InterfaceData updatedInterfaceData = new InterfaceData(newInterfaceInfo);
+        Either<InterfaceData, TitanOperationStatus> createStatus = createInterfaceNodeAndRelation(interfaceName, resourceId, updatedInterfaceData, resourceData);
+        if (createStatus.isRight()) {
+            log.debug("failed to create interface node  {} on resource  {}", interfaceName,  resourceId);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createStatus.right().value()));
+        }
 
-		InterfaceData newInterfaceNode = createStatus.left().value();
-		Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(newInterfaceNode, interfaceData, GraphEdgeLabels.DERIVED_FROM, null);
-		if (createRelResult.isRight()) {
-			TitanOperationStatus operationStatus = createRelResult.right().value();
-			log.error("Failed to associate interface {} to interface {} in graph. status is {}", interfaceData.getUniqueId(), newInterfaceNode.getUniqueId(),  operationStatus);
+        InterfaceData newInterfaceNode = createStatus.left().value();
+        Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(newInterfaceNode, interfaceData, GraphEdgeLabels.DERIVED_FROM, null);
+        if (createRelResult.isRight()) {
+            TitanOperationStatus operationStatus = createRelResult.right().value();
+            log.error("Failed to associate interface {} to interface {} in graph. status is {}", interfaceData.getUniqueId(), newInterfaceNode.getUniqueId(),  operationStatus);
 
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
-		}
-		Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) interfaceData.getUniqueId(),
-				GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
-		if (operationRes.isRight()) {
-			log.error("Failed to find operation  {} on interface {}", operationName, interfaceName);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
+        }
+        Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) interfaceData.getUniqueId(),
+                GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
+        if (operationRes.isRight()) {
+            log.error("Failed to find operation  {} on interface {}", operationName, interfaceName);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
 
-		} else {
-			List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value();
-			for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) {
-				GraphEdge opEdge = operationPairEdge.getRight();
-				OperationData opData = operationPairEdge.getLeft();
-				Map<String, Object> opEdgeProp = opEdge.getProperties();
-				if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) {
+        } else {
+            List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value();
+            for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) {
+                GraphEdge opEdge = operationPairEdge.getRight();
+                OperationData opData = operationPairEdge.getLeft();
+                Map<String, Object> opEdgeProp = opEdge.getProperties();
+                if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) {
 
-					return copyAndCreateNewOperation(operation, interfaceName, operationName, null, // changed
-																									// from
-																									// newOperation
-							newInterfaceNode, operationRes, opData);
+                    return copyAndCreateNewOperation(operation, interfaceName, operationName, null, // changed
+                                                                                                    // from
+                                                                                                    // newOperation
+                            newInterfaceNode, operationRes, opData);
 
-				}
-			}
-		}
-		return Either.right(StorageOperationStatus.GENERAL_ERROR);
-	}
+                }
+            }
+        }
+        return Either.right(StorageOperationStatus.GENERAL_ERROR);
+    }
 
-	private Either<InterfaceData, TitanOperationStatus> findInterfaceOnParentNode(String resourceId, String interfaceName) {
+    private Either<InterfaceData, TitanOperationStatus> findInterfaceOnParentNode(String resourceId, String interfaceName) {
 
-		Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentRes = titanGenericDao.getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
-				ResourceMetadataData.class);
-		if (parentRes.isRight()) {
-			log.debug("interface {} not found ", interfaceName);
-			return Either.right(parentRes.right().value());
-		}
-		ImmutablePair<ResourceMetadataData, GraphEdge> parenNode = parentRes.left().value();
+        Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentRes = titanGenericDao.getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
+                ResourceMetadataData.class);
+        if (parentRes.isRight()) {
+            log.debug("interface {} not found ", interfaceName);
+            return Either.right(parentRes.right().value());
+        }
+        ImmutablePair<ResourceMetadataData, GraphEdge> parenNode = parentRes.left().value();
 
-		Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), parenNode.getKey().getMetadataDataDefinition().getUniqueId(),
-				GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface, InterfaceData.class);
-		if (childrenNodes.isRight()) {
-			return findInterfaceOnParentNode(parenNode.getKey().getMetadataDataDefinition().getUniqueId(), interfaceName);
+        Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), parenNode.getKey().getMetadataDataDefinition().getUniqueId(),
+                GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface, InterfaceData.class);
+        if (childrenNodes.isRight()) {
+            return findInterfaceOnParentNode(parenNode.getKey().getMetadataDataDefinition().getUniqueId(), interfaceName);
 
-		} else {
-			for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) {
+        } else {
+            for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) {
 
-				GraphEdge interfaceEdge = interfaceDataNode.getRight();
-				Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties();
+                GraphEdge interfaceEdge = interfaceDataNode.getRight();
+                Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties();
 
-				if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceName)) {
-					return Either.left(interfaceDataNode.getKey());
-				}
+                if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceName)) {
+                    return Either.left(interfaceDataNode.getKey());
+                }
 
-			}
-			return findInterfaceOnParentNode(parenNode.getKey().getMetadataDataDefinition().getUniqueId(), interfaceName);
-		}
+            }
+            return findInterfaceOnParentNode(parenNode.getKey().getMetadataDataDefinition().getUniqueId(), interfaceName);
+        }
 
-	}
+    }
 
-	@Override
-	public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceOnResource(InterfaceDefinition interf, String resourceId, String interfaceName, boolean failIfExist, boolean inTransaction) {
+    @Override
+    public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceOnResource(InterfaceDefinition interf, String resourceId, String interfaceName, boolean failIfExist, boolean inTransaction) {
 
-		Either<InterfaceData, TitanOperationStatus> status = addInterfaceToGraph(interf, interfaceName, resourceId);
+        Either<InterfaceData, TitanOperationStatus> status = addInterfaceToGraph(interf, interfaceName, resourceId);
 
-		if (status.isRight()) {
-			titanGenericDao.rollback();
-			log.error("Failed to add interface {} to resource {}", interfaceName, resourceId);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value()));
-		} else {
+        if (status.isRight()) {
+            titanGenericDao.rollback();
+            log.error("Failed to add interface {} to resource {}", interfaceName, resourceId);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value()));
+        } else {
 
-			if (false == inTransaction) {
-				titanGenericDao.commit();
-			}
-			InterfaceData interfaceData = status.left().value();
+            if (!inTransaction) {
+                titanGenericDao.commit();
+            }
+            InterfaceData interfaceData = status.left().value();
 
-			InterfaceDefinition interfaceDefResult = convertInterfaceDataToInterfaceDefinition(interfaceData);
-			Map<String, Operation> operations = interf.getOperationsMap();
-			if (operations != null && !operations.isEmpty()) {
-				Set<String> opNames = operations.keySet();
-				Map<String, Operation> newOperations = new HashMap<String, Operation>();
-				for (String operationName : opNames) {
+            InterfaceDefinition interfaceDefResult = convertInterfaceDataToInterfaceDefinition(interfaceData);
+            Map<String, Operation> operations = interf.getOperationsMap();
+            if (operations != null && !operations.isEmpty()) {
+                Set<String> opNames = operations.keySet();
+                Map<String, Operation> newOperations = new HashMap<>();
+                for (String operationName : opNames) {
 
-					Operation op = operations.get(operationName);
-					Either<OperationData, TitanOperationStatus> opStatus = addOperationToGraph(interf, operationName, op, interfaceData);
-					if (status.isRight()) {
-						titanGenericDao.rollback();
-						log.error("Failed to add operation {} to interface {}", operationName, interfaceName);
-					} else if (status.isLeft()) {
-						if (false == inTransaction) {
-							titanGenericDao.commit();
-						}
-						OperationData opData = opStatus.left().value();
-						Operation newOperation = this.convertOperationDataToOperation(opData);
+                    Operation op = operations.get(operationName);
+                    Either<OperationData, TitanOperationStatus> opStatus = addOperationToGraph(interf, operationName, op, interfaceData);
+                    if (status.isRight()) {
+                        titanGenericDao.rollback();
+                        log.error("Failed to add operation {} to interface {}", operationName, interfaceName);
+                    } else if (status.isLeft()) {
+                        if (!inTransaction) {
+                            titanGenericDao.commit();
+                        }
+                        OperationData opData = opStatus.left().value();
+                        Operation newOperation = this.convertOperationDataToOperation(opData);
 
-						ArtifactDefinition art = op.getImplementationArtifact();
-						if (art != null) {
-							Either<ArtifactDefinition, StorageOperationStatus> artRes = artifactOperation.addArifactToComponent(art, (String) opData.getUniqueId(), NodeTypeEnum.InterfaceOperation, failIfExist, true);
-							if (artRes.isRight()) {
-								titanGenericDao.rollback();
-								log.error("Failed to add artifact {} to interface {}", operationName, interfaceName);
-							} else {
-								newOperation.setImplementation(artRes.left().value());
-							}
-							newOperations.put(operationName, newOperation);
-						}
-					}
-				}
-				interfaceDefResult.setOperationsMap(newOperations);
-			}
-			log.debug("The returned InterfaceDefintion is {}", interfaceDefResult);
-			return Either.left(interfaceDefResult);
-		}
+                        ArtifactDefinition art = op.getImplementationArtifact();
+                        if (art != null) {
+                            Either<ArtifactDefinition, StorageOperationStatus> artRes = artifactOperation.addArifactToComponent(art, (String) opData.getUniqueId(), NodeTypeEnum.InterfaceOperation, failIfExist, true);
+                            if (artRes.isRight()) {
+                                titanGenericDao.rollback();
+                                log.error("Failed to add artifact {} to interface {}", operationName, interfaceName);
+                            } else {
+                                newOperation.setImplementation(artRes.left().value());
+                            }
+                            newOperations.put(operationName, newOperation);
+                        }
+                    }
+                }
+                interfaceDefResult.setOperationsMap(newOperations);
+            }
+            log.debug("The returned InterfaceDefintion is {}", interfaceDefResult);
+            return Either.left(interfaceDefResult);
+        }
 
-	}
+    }
 
-	@Override
-	public Either<Operation, StorageOperationStatus> deleteInterfaceOperation(String resourceId, String interfaceName, String operationId, boolean inTransaction) {
+    @Override
+    public Either<Operation, StorageOperationStatus> deleteInterfaceOperation(String resourceId, String interfaceName, String operationId, boolean inTransaction) {
 
-		Either<Operation, TitanOperationStatus> status = removeOperationOnGraph(resourceId, interfaceName, operationId);
-		if (status.isRight()) {
-			if (false == inTransaction) {
-				titanGenericDao.rollback();
-			}
-			log.error("Failed to delete operation {} of interface {} resource {}", operationId, interfaceName, resourceId);
-			return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value()));
-		} else {
-			if (false == inTransaction) {
-				titanGenericDao.commit();
-			}
+        Either<Operation, TitanOperationStatus> status = removeOperationOnGraph(resourceId, interfaceName, operationId);
+        if (status.isRight()) {
+            if (!inTransaction) {
+                titanGenericDao.rollback();
+            }
+            log.error("Failed to delete operation {} of interface {} resource {}", operationId, interfaceName, resourceId);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value()));
+        } else {
+            if (!inTransaction) {
+                titanGenericDao.commit();
+            }
 
-			Operation opDefResult = status.left().value();// convertOperationDataToOperation(operationData);
-			log.debug("The returned Operation is {}", opDefResult);
-			return Either.left(opDefResult);
-		}
+            Operation opDefResult = status.left().value();// convertOperationDataToOperation(operationData);
+            log.debug("The returned Operation is {}", opDefResult);
+            return Either.left(opDefResult);
+        }
 
-	}
+    }
 
-	private Either<Operation, TitanOperationStatus> removeOperationOnGraph(String resourceId, String interfaceName, String operationId) {
-		log.debug("Before deleting operation from graph {}", operationId);
+    private Either<Operation, TitanOperationStatus> removeOperationOnGraph(String resourceId, String interfaceName, String operationId) {
+        log.debug("Before deleting operation from graph {}", operationId);
 
-		Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface,
-				InterfaceData.class);
+        Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface,
+                InterfaceData.class);
 
-		if (childrenNodes.isRight()) {
-			log.debug("Not found interface {}", interfaceName);
-			return Either.right(childrenNodes.right().value());
-		}
-		OperationData opData = null;
-		for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) {
+        if (childrenNodes.isRight()) {
+            log.debug("Not found interface {}", interfaceName);
+            return Either.right(childrenNodes.right().value());
+        }
+        OperationData opData = null;
+        for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) {
 
-			GraphEdge interfaceEdge = interfaceDataNode.getRight();
-			Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties();
+            GraphEdge interfaceEdge = interfaceDataNode.getRight();
+            Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties();
 
-			String interfaceSplitedName = splitType(interfaceName);
+            String interfaceSplitedName = splitType(interfaceName);
 
-			if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceSplitedName)) {
-				Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) interfaceDataNode.getLeft().getUniqueId(),
-						GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
-				if (operationRes.isRight()) {
-					log.error("Failed to find operation {} on interface {}", operationId, interfaceName);
-					return Either.right(operationRes.right().value());
-				}
-				List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value();
+            if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceSplitedName)) {
+                Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) interfaceDataNode.getLeft().getUniqueId(),
+                        GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
+                if (operationRes.isRight()) {
+                    log.error("Failed to find operation {} on interface {}", operationId, interfaceName);
+                    return Either.right(operationRes.right().value());
+                }
+                List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value();
 
-				for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) {
+                for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) {
 
-					opData = operationPairEdge.getLeft();
-					if (opData.getUniqueId().equals(operationId)) {
+                    opData = operationPairEdge.getLeft();
+                    if (opData.getUniqueId().equals(operationId)) {
 
-						Either<ImmutablePair<ArtifactData, GraphEdge>, TitanOperationStatus> artifactRes = titanGenericDao.getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) operationPairEdge.getLeft().getUniqueId(),
-								GraphEdgeLabels.ARTIFACT_REF, NodeTypeEnum.ArtifactRef, ArtifactData.class);
-						Either<ArtifactDefinition, StorageOperationStatus> arStatus = null;
-						if (artifactRes.isLeft()) {
-							ArtifactData arData = artifactRes.left().value().getKey();
-							arStatus = artifactOperation.removeArifactFromResource((String) operationPairEdge.getLeft().getUniqueId(), (String) arData.getUniqueId(), NodeTypeEnum.InterfaceOperation, true, true);
-							if (arStatus.isRight()) {
-								log.debug("failed to delete artifact {}", arData.getUniqueId());
-								return Either.right(TitanOperationStatus.INVALID_ID);
-							}
-						}
-						Either<OperationData, TitanOperationStatus> deleteOpStatus = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InterfaceOperation), opData.getUniqueId(), OperationData.class);
-						if (deleteOpStatus.isRight()) {
-							log.debug("failed to delete operation {}", opData.getUniqueId());
-							return Either.right(TitanOperationStatus.INVALID_ID);
-						}
-						opData = deleteOpStatus.left().value();
-						Operation operation = new Operation(opData.getOperationDataDefinition());
-						if (arStatus != null) {
-							operation.setImplementation(arStatus.left().value());
-						}
-						if (operations.size() <= 1) {
-							Either<InterfaceData, TitanOperationStatus> deleteInterfaceStatus = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceDataNode.left.getUniqueId(), InterfaceData.class);
-							if (deleteInterfaceStatus.isRight()) {
-								log.debug("failed to delete interface {}", interfaceDataNode.left.getUniqueId());
-								return Either.right(TitanOperationStatus.INVALID_ID);
-							}
+                        Either<ImmutablePair<ArtifactData, GraphEdge>, TitanOperationStatus> artifactRes = titanGenericDao.getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) operationPairEdge.getLeft().getUniqueId(),
+                                GraphEdgeLabels.ARTIFACT_REF, NodeTypeEnum.ArtifactRef, ArtifactData.class);
+                        Either<ArtifactDefinition, StorageOperationStatus> arStatus = null;
+                        if (artifactRes.isLeft()) {
+                            ArtifactData arData = artifactRes.left().value().getKey();
+                            arStatus = artifactOperation.removeArifactFromResource((String) operationPairEdge.getLeft().getUniqueId(), (String) arData.getUniqueId(), NodeTypeEnum.InterfaceOperation, true, true);
+                            if (arStatus.isRight()) {
+                                log.debug("failed to delete artifact {}", arData.getUniqueId());
+                                return Either.right(TitanOperationStatus.INVALID_ID);
+                            }
+                        }
+                        Either<OperationData, TitanOperationStatus> deleteOpStatus = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InterfaceOperation), opData.getUniqueId(), OperationData.class);
+                        if (deleteOpStatus.isRight()) {
+                            log.debug("failed to delete operation {}", opData.getUniqueId());
+                            return Either.right(TitanOperationStatus.INVALID_ID);
+                        }
+                        opData = deleteOpStatus.left().value();
+                        Operation operation = new Operation(opData.getOperationDataDefinition());
+                        if (arStatus != null) {
+                            operation.setImplementation(arStatus.left().value());
+                        }
+                        if (operations.size() <= 1) {
+                            Either<InterfaceData, TitanOperationStatus> deleteInterfaceStatus = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceDataNode.left.getUniqueId(), InterfaceData.class);
+                            if (deleteInterfaceStatus.isRight()) {
+                                log.debug("failed to delete interface {}", interfaceDataNode.left.getUniqueId());
+                                return Either.right(TitanOperationStatus.INVALID_ID);
+                            }
 
-						}
+                        }
 
-						return Either.left(operation);
+                        return Either.left(operation);
 
-					}
-				}
-			}
-		}
+                    }
+                }
+            }
+        }
 
-		log.debug("Not found operation {}", interfaceName);
-		return Either.right(TitanOperationStatus.INVALID_ID);
-	}
+        log.debug("Not found operation {}", interfaceName);
+        return Either.right(TitanOperationStatus.INVALID_ID);
+    }
 
-	private String splitType(String interfaceName) {
-		String interfaceSplittedName;
-		String[] packageName = interfaceName.split("\\.");
+    private String splitType(String interfaceName) {
+        String interfaceSplittedName;
+        String[] packageName = interfaceName.split("\\.");
 
-		if (packageName.length == 0) {
-			interfaceSplittedName = interfaceName;
-		} else {
-			interfaceSplittedName = packageName[packageName.length - 1];
-		}
+        if (packageName.length == 0) {
+            interfaceSplittedName = interfaceName;
+        } else {
+            interfaceSplittedName = packageName[packageName.length - 1];
+        }
 
-		return interfaceSplittedName.toLowerCase();
-	}
+        return interfaceSplittedName.toLowerCase();
+    }
 
-	/**
-	 * FOR TEST ONLY
-	 * 
-	 * @param titanGenericDao
-	 */
-	public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
-		this.titanGenericDao = titanGenericDao;
-	}
+    /**
+     * FOR TEST ONLY
+     *
+     * @param titanGenericDao
+     */
+    public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
+        this.titanGenericDao = titanGenericDao;
+    }
 
-	public void setArtifactOperation(ArtifactOperation artifactOperation) {
-		this.artifactOperation = artifactOperation;
-	}
+    public void setArtifactOperation(ArtifactOperation artifactOperation) {
+        this.artifactOperation = artifactOperation;
+    }
 
-	@Override
-	public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf, boolean inTransaction) {
-		Either<InterfaceDefinition, StorageOperationStatus> result = null;
-		try {
+    @Override
+    public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf, boolean inTransaction) {
+        Either<InterfaceDefinition, StorageOperationStatus> result = null;
+        try {
 
-			InterfaceData interfaceData = new InterfaceData(interf);
-			interf.setUniqueId(interf.getType().toLowerCase());
+            InterfaceData interfaceData = new InterfaceData(interf);
+            interf.setUniqueId(interf.getType().toLowerCase());
 
-			Either<InterfaceData, TitanOperationStatus> existInterface = titanGenericDao.getNode(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId(), InterfaceData.class);
+            Either<InterfaceData, TitanOperationStatus> existInterface = titanGenericDao.getNode(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId(), InterfaceData.class);
 
-			if (existInterface.isLeft()) {
-				// already exist
-				log.debug("Interface type already exist {}", interfaceData);
-				result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
-				return result;
-			}
+            if (existInterface.isLeft()) {
+                // already exist
+                log.debug("Interface type already exist {}", interfaceData);
+                result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
+                return result;
+            }
 
-			log.debug("Before adding interface type to graph {}", interfaceData);
-			Either<InterfaceData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(interfaceData, InterfaceData.class);
-			log.debug("After adding property type to graph {}", interfaceData);
+            log.debug("Before adding interface type to graph {}", interfaceData);
+            Either<InterfaceData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(interfaceData, InterfaceData.class);
+            log.debug("After adding property type to graph {}", interfaceData);
 
-			if (createNodeResult.isRight()) {
-				TitanOperationStatus operationStatus = createNodeResult.right().value();
-				log.error("Failed to add interface {} to graph. status is {}", interf.getType(), operationStatus);
-				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
-				return result;
-			}
+            if (createNodeResult.isRight()) {
+                TitanOperationStatus operationStatus = createNodeResult.right().value();
+                log.error("Failed to add interface {} to graph. status is {}", interf.getType(), operationStatus);
+                result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
+                return result;
+            }
 
-			InterfaceDefinition interfaceDefResult = convertInterfaceDataToInterfaceDefinition(interfaceData);
-			Map<String, Operation> operations = interf.getOperationsMap();
+            InterfaceDefinition interfaceDefResult = convertInterfaceDataToInterfaceDefinition(interfaceData);
+            Map<String, Operation> operations = interf.getOperationsMap();
 
-			if (operations != null && !operations.isEmpty()) {
-				Map<String, Operation> newOperations = new HashMap<String, Operation>();
+            if (operations != null && !operations.isEmpty()) {
+                Map<String, Operation> newOperations = new HashMap<>();
 
-				for (Map.Entry<String, Operation> operation : operations.entrySet()) {
-					Either<OperationData, TitanOperationStatus> opStatus = addOperationToGraph(interf, operation.getKey(), operation.getValue(), interfaceData);
-					if (opStatus.isRight()) {
-						titanGenericDao.rollback();
-						log.error("Failed to add operation {} to interface {}", operation.getKey(), interf.getType());
+                for (Map.Entry<String, Operation> operation : operations.entrySet()) {
+                    Either<OperationData, TitanOperationStatus> opStatus = addOperationToGraph(interf, operation.getKey(), operation.getValue(), interfaceData);
+                    if (opStatus.isRight()) {
+                        titanGenericDao.rollback();
+                        log.error("Failed to add operation {} to interface {}", operation.getKey(), interf.getType());
 
-						result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(opStatus.right().value()));
-						return result;
-					} else {
-						OperationData opData = opStatus.left().value();
-						Operation newOperation = this.convertOperationDataToOperation(opData);
-						newOperations.put(operation.getKey(), newOperation);
-					}
-				}
-				interfaceDefResult.setOperationsMap(newOperations);
-			}
-			result = Either.left(interfaceDefResult);
-			return result;
-		} finally {
-			if (false == inTransaction) {
-				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
-					titanGenericDao.rollback();
-				} else {
-					log.debug("Going to execute commit on graph.");
-					titanGenericDao.commit();
-				}
-			}
-		}
+                        result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(opStatus.right().value()));
+                        return result;
+                    } else {
+                        OperationData opData = opStatus.left().value();
+                        Operation newOperation = this.convertOperationDataToOperation(opData);
+                        newOperations.put(operation.getKey(), newOperation);
+                    }
+                }
+                interfaceDefResult.setOperationsMap(newOperations);
+            }
+            result = Either.left(interfaceDefResult);
+            return result;
+        } finally {
+            if (!inTransaction) {
+                if (result == null || result.isRight()) {
+                    log.error("Going to execute rollback on graph.");
+                    titanGenericDao.rollback();
+                } else {
+                    log.debug("Going to execute commit on graph.");
+                    titanGenericDao.commit();
+                }
+            }
+        }
 
-	}
+    }
 
-	@Override
-	public Either<InterfaceDefinition, StorageOperationStatus> getInterface(String interfaceId) {
-		Either<InterfaceData, TitanOperationStatus> getResult = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceId, InterfaceData.class);
-		if (getResult.isLeft()) {
-			InterfaceData interfaceData = getResult.left().value();
-			return Either.left(convertInterfaceDataToInterfaceDefinition(interfaceData));
-		} else {
-			TitanOperationStatus titanStatus = getResult.right().value();
-			log.debug("Node with id {} was not found in the graph. status: {}", interfaceId, titanStatus);
-			StorageOperationStatus storageOperationStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
-			return Either.right(storageOperationStatus);
-		}
-	}
+    @Override
+    public Either<InterfaceDefinition, StorageOperationStatus> getInterface(String interfaceId) {
+        Either<InterfaceData, TitanOperationStatus> getResult = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceId, InterfaceData.class);
+        if (getResult.isLeft()) {
+            InterfaceData interfaceData = getResult.left().value();
+            return Either.left(convertInterfaceDataToInterfaceDefinition(interfaceData));
+        } else {
+            TitanOperationStatus titanStatus = getResult.right().value();
+            log.debug("Node with id {} was not found in the graph. status: {}", interfaceId, titanStatus);
+            StorageOperationStatus storageOperationStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
+            return Either.right(storageOperationStatus);
+        }
+    }
 
-	public String getShortInterfaceName(InterfaceDataDefinition interfaceDefinition) {
-		String[] packageName = interfaceDefinition.getType().split("\\.");
-		String interfaceName;
-		if (packageName.length == 0) {
-			interfaceName = interfaceDefinition.getType();
-		} else {
-			interfaceName = packageName[packageName.length - 1];
-		}
-		return interfaceName.toLowerCase();
-	}
+    public String getShortInterfaceName(InterfaceDataDefinition interfaceDefinition) {
+        String[] packageName = interfaceDefinition.getType().split("\\.");
+        String interfaceName;
+        if (packageName.length == 0) {
+            interfaceName = interfaceDefinition.getType();
+        } else {
+            interfaceName = packageName[packageName.length - 1];
+        }
+        return interfaceName.toLowerCase();
+    }
 
-	/** 
-	 * 
-	 */
-	public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf) {
-		return createInterfaceType(interf, false);
-	}
+    /**
+     *
+     */
+    public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf) {
+        return createInterfaceType(interf, false);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/Neo4jStatusConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/Neo4jStatusConverter.java
new file mode 100644
index 0000000..6093eb0
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/Neo4jStatusConverter.java
@@ -0,0 +1,78 @@
+/*-
+ * ============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.be.model.operations.impl;
+
+import org.openecomp.sdc.be.dao.neo4j.Neo4jOperationStatus;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+
+public class Neo4jStatusConverter {
+
+    public static StorageOperationStatus convertNeo4jStatusToStorageStatus(Neo4jOperationStatus neo4jStatus) {
+
+        if (neo4jStatus == null) {
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+
+        switch (neo4jStatus) {
+
+        case OK:
+            return StorageOperationStatus.OK;
+
+        case NOT_CONNECTED:
+            return StorageOperationStatus.CONNECTION_FAILURE;
+
+        case NOT_AUTHORIZED:
+            return StorageOperationStatus.PERMISSION_ERROR;
+
+        case HTTP_PROTOCOL_ERROR:
+            return StorageOperationStatus.HTTP_PROTOCOL_ERROR;
+        case DB_NOT_AVAILABLE:
+            return StorageOperationStatus.STORAGE_NOT_AVAILABLE;
+        case DB_READ_ONLY:
+            return StorageOperationStatus.READ_ONLY_STORAGE;
+        case BAD_REQUEST:
+            return StorageOperationStatus.BAD_REQUEST;
+        case LEGACY_INDEX_ERROR:
+            return StorageOperationStatus.STORAGE_LEGACY_INDEX_ERROR;
+        case SCHEMA_ERROR:
+            return StorageOperationStatus.SCHEMA_ERROR;
+        case TRANSACTION_ERROR:
+            return StorageOperationStatus.TRANSACTION_ERROR;
+        case EXECUTION_FAILED:
+            return StorageOperationStatus.EXEUCTION_FAILED;
+        case ENTITY_ALREADY_EXIST:
+            return StorageOperationStatus.ENTITY_ALREADY_EXISTS;
+        case WRONG_INPUT:
+            return StorageOperationStatus.BAD_REQUEST;
+        case GENERAL_ERROR:
+            return StorageOperationStatus.GENERAL_ERROR;
+        case NOT_SUPPORTED:
+            return StorageOperationStatus.OPERATION_NOT_SUPPORTED;
+        case NOT_FOUND:
+            return StorageOperationStatus.NOT_FOUND;
+
+        default:
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+
+    }
+
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java
index 7d299c8..8e1ee19 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java
@@ -20,13 +20,7 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.Map;
-import java.util.Properties;
-
+import fj.data.Either;
 import org.apache.commons.io.filefilter.WildcardFileFilter;
 import org.apache.http.HttpStatus;
 import org.openecomp.sdc.be.config.Configuration.OnboardingConfig;
@@ -35,155 +29,157 @@
 import org.openecomp.sdc.common.api.Constants;
 import org.openecomp.sdc.common.http.client.api.HttpRequest;
 import org.openecomp.sdc.common.http.client.api.HttpResponse;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ZipUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import fj.data.Either;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Map;
+import java.util.Properties;
 
 @org.springframework.stereotype.Component("onboarding-client")
 public class OnboardingClient {
 
-	private static Logger log = LoggerFactory.getLogger(OnboardingClient.class.getName());
+    private static final Logger log = Logger.getLogger(OnboardingClient.class.getName());
 
-	private static Properties downloadCsarHeaders = new Properties();
+    private static Properties downloadCsarHeaders = new Properties();
 
-	static {
-		downloadCsarHeaders.put("Accept", "application/octet-stream");
-	}
+    static {
+        downloadCsarHeaders.put("Accept", "application/octet-stream");
+    }
 
-	public OnboardingClient() {
-		super();
-	}
+    public OnboardingClient() {
+        super();
+    }
 
-	public static void main(String[] args) {
+    public static void main(String[] args) {
 
-		OnboardingClient csarOperation = new OnboardingClient();
+        OnboardingClient csarOperation = new OnboardingClient();
 
-		String csarUuid = "70025CF6081B489CA7B1CBA583D5278D";
-		Either<Map<String, byte[]>, StorageOperationStatus> csar = csarOperation.getCsar(csarUuid, null);
-		System.out.println(csar.left().value());
+        String csarUuid = "70025CF6081B489CA7B1CBA583D5278D";
+        Either<Map<String, byte[]>, StorageOperationStatus> csar = csarOperation.getCsar(csarUuid, null);
+        System.out.println(csar.left().value());
 
-	}
+    }
 
-	public Either<Map<String, byte[]>, StorageOperationStatus> getMockCsar(String csarUuid) {
-		File dir = new File("/var/tmp/mockCsar");
-		FileFilter fileFilter = new WildcardFileFilter("*.csar");
-		File[] files = dir.listFiles(fileFilter);
-		for (int i = 0; i < files.length; i++) {
-			File csar = files[i];
-			if (csar.getName().startsWith(csarUuid)) {
-				log.debug("Found CSAR file {} matching the passed csarUuid {}", csar.getAbsolutePath(), csarUuid);
-				byte[] data;
-				try {
-					data = Files.readAllBytes(csar.toPath());
-				} catch (IOException e) {
-					log.debug("Error reading mock file for CSAR, error: {}", e);
-					return Either.right(StorageOperationStatus.NOT_FOUND);
-				}
-				Map<String, byte[]> readZip = ZipUtil.readZip(data);
-				return Either.left(readZip);
-			}
-		}
-		log.debug("Couldn't find mock file for CSAR starting with {}", csarUuid);
-		return Either.right(StorageOperationStatus.NOT_FOUND);
-	}
+    public Either<Map<String, byte[]>, StorageOperationStatus> getMockCsar(String csarUuid) {
+        File dir = new File("/var/tmp/mockCsar");
+        FileFilter fileFilter = new WildcardFileFilter("*.csar");
+        File[] files = dir.listFiles(fileFilter);
+        for (int i = 0; i < files.length; i++) {
+            File csar = files[i];
+            if (csar.getName().startsWith(csarUuid)) {
+                log.debug("Found CSAR file {} matching the passed csarUuid {}", csar.getAbsolutePath(), csarUuid);
+                byte[] data;
+                try {
+                    data = Files.readAllBytes(csar.toPath());
+                } catch (IOException e) {
+                    log.debug("Error reading mock file for CSAR, error: {}", e);
+                    return Either.right(StorageOperationStatus.NOT_FOUND);
+                }
+                Map<String, byte[]> readZip = ZipUtil.readZip(data);
+                return Either.left(readZip);
+            }
+        }
+        log.debug("Couldn't find mock file for CSAR starting with {}", csarUuid);
+        return Either.right(StorageOperationStatus.NOT_FOUND);
+    }
 
-	public Either<Map<String, byte[]>, StorageOperationStatus> getCsar(String csarUuid, String userId) {
-		String url = buildDownloadCsarUrl() + "/" + csarUuid;
+    public Either<Map<String, byte[]>, StorageOperationStatus> getCsar(String csarUuid, String userId) {
+        String url = buildDownloadCsarUrl() + "/" + csarUuid;
 
-		Properties headers = new Properties();
-		if (downloadCsarHeaders != null) {
-			downloadCsarHeaders.forEach((k, v) -> headers.put(k, v));
-		}
+        Properties headers = new Properties();
+        if (downloadCsarHeaders != null) {
+            downloadCsarHeaders.forEach(headers::put);
+        }
 
-		if (userId != null) {
-			headers.put(Constants.USER_ID_HEADER, userId);
-		}
+        if (userId != null) {
+            headers.put(Constants.USER_ID_HEADER, userId);
+        }
 
-		log.debug("Url for downloading csar is {}. Headers are {}", url, headers);
+        log.debug("Url for downloading csar is {}. Headers are {}", url, headers);
 
-		try {
-    		HttpResponse<byte []> httpResponse = HttpRequest.getAsByteArray(url, headers);
-    		log.debug("After fetching csar {}. Http return code is {}", csarUuid, httpResponse.getStatusCode());
+        try {
+            HttpResponse<byte []> httpResponse = HttpRequest.getAsByteArray(url, headers);
+            log.debug("After fetching csar {}. Http return code is {}", csarUuid, httpResponse.getStatusCode());
     
-    		switch (httpResponse.getStatusCode()) {
-    		case HttpStatus.SC_OK:
-    			byte[] data = httpResponse.getResponse();
-    			if (data != null && data.length > 0) {
-    				Map<String, byte[]> readZip = ZipUtil.readZip(data);
-    				return Either.left(readZip);
-    			} else {
-    				log.debug("Data received from rest is null or empty");
-    				return Either.right(StorageOperationStatus.NOT_FOUND);
-    			}
+            switch (httpResponse.getStatusCode()) {
+            case HttpStatus.SC_OK:
+                byte[] data = httpResponse.getResponse();
+                if (data != null && data.length > 0) {
+                    Map<String, byte[]> readZip = ZipUtil.readZip(data);
+                    return Either.left(readZip);
+                } else {
+                    log.debug("Data received from rest is null or empty");
+                    return Either.right(StorageOperationStatus.NOT_FOUND);
+                }
     
-    		case HttpStatus.SC_NOT_FOUND:
-    			return Either.right(StorageOperationStatus.CSAR_NOT_FOUND);
+            case HttpStatus.SC_NOT_FOUND:
+                return Either.right(StorageOperationStatus.CSAR_NOT_FOUND);
     
-    		default:
-    			return Either.right(StorageOperationStatus.GENERAL_ERROR);
-    		}
-		}
-		catch(Exception e) {
-		    log.debug("Request failed with exception {}", e);
-		    return Either.right(StorageOperationStatus.GENERAL_ERROR);
-		}
-	}
-	
-	public Either<String, StorageOperationStatus> getPackages(String userId) {
-		String url = buildDownloadCsarUrl();
-
-		Properties headers = new Properties();
-		headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
-
-		if (userId != null) {
-			headers.put(Constants.USER_ID_HEADER, userId);
-		}
-
-		log.debug("Url for downloading packages is {}. Headers are {}", url, headers);
-
-		try {
-    		HttpResponse<String> httpResposne = HttpRequest.get(url, headers);
-    		log.debug("After fetching packages. Http return code is {}", httpResposne.getStatusCode());
-    
-    		switch (httpResposne.getStatusCode()) {
-    		case HttpStatus.SC_OK:
-    			String data = httpResposne.getResponse();
-    			return Either.left(data);
-    
-    		case HttpStatus.SC_NOT_FOUND:
-    			return Either.right(StorageOperationStatus.CSAR_NOT_FOUND);
-    
-    		default:
-    			return Either.right(StorageOperationStatus.GENERAL_ERROR);
-    		}
-		}
-		catch(Exception e) {
+            default:
+                return Either.right(StorageOperationStatus.GENERAL_ERROR);
+            }
+        }
+        catch(Exception e) {
             log.debug("Request failed with exception {}", e);
             return Either.right(StorageOperationStatus.GENERAL_ERROR);
-		}
-	}
+        }
+    }
 
-	/**
-	 * Build the url for download CSAR
-	 * 
-	 * E.g., http://0.0.0.0:8181/onboarding-api/v1.0/vendor-software-products/packages/
-	 * 
-	 * @return
-	 */
-	public String buildDownloadCsarUrl() {
+    public Either<String, StorageOperationStatus> getPackages(String userId) {
+        String url = buildDownloadCsarUrl();
 
-		OnboardingConfig onboardingConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getOnboarding();
+        Properties headers = new Properties();
+        headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
 
-		String protocol = onboardingConfig.getProtocol();
-		String host = onboardingConfig.getHost();
-		Integer port = onboardingConfig.getPort();
-		String uri = onboardingConfig.getDownloadCsarUri();
+        if (userId != null) {
+            headers.put(Constants.USER_ID_HEADER, userId);
+        }
 
-		String getCsarUrl = protocol + "://" + host + ":" + port + uri;
+        log.debug("Url for downloading packages is {}. Headers are {}", url, headers);
 
-		return getCsarUrl;
-	}
+        try {
+            HttpResponse<String> httpResposne = HttpRequest.get(url, headers);
+            log.debug("After fetching packages. Http return code is {}", httpResposne.getStatusCode());
+    
+            switch (httpResposne.getStatusCode()) {
+            case HttpStatus.SC_OK:
+                String data = httpResposne.getResponse();
+                return Either.left(data);
+    
+            case HttpStatus.SC_NOT_FOUND:
+                return Either.right(StorageOperationStatus.CSAR_NOT_FOUND);
+    
+            default:
+                return Either.right(StorageOperationStatus.GENERAL_ERROR);
+            }
+        }
+        catch(Exception e) {
+            log.debug("Request failed with exception {}", e);
+            return Either.right(StorageOperationStatus.GENERAL_ERROR);
+        }
+    }
+
+    /**
+     * Build the url for download CSAR
+     *
+     * E.g., http://0.0.0.0:8181/onboarding-api/v1.0/vendor-software-products/packages/
+     *
+     * @return
+     */
+    public String buildDownloadCsarUrl() {
+
+        OnboardingConfig onboardingConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getOnboarding();
+
+        String protocol = onboardingConfig.getProtocol();
+        String host = onboardingConfig.getHost();
+        Integer port = onboardingConfig.getPort();
+        String uri = onboardingConfig.getDownloadCsarUri();
+
+        return protocol + "://" + host + ":" + port + uri;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OperationUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OperationUtils.java
new file mode 100644
index 0000000..dcaafe5
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OperationUtils.java
@@ -0,0 +1,21 @@
+package org.openecomp.sdc.be.model.operations.impl;
+
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.model.operations.StorageException;
+import org.springframework.stereotype.Component;
+
+@Component
+public class OperationUtils {
+
+    private final TitanDao titanDao;
+
+    public OperationUtils(TitanDao titanDao) {
+        this.titanDao = titanDao;
+    }
+
+    public <T> T onTitanOperationFailure(TitanOperationStatus status) {
+        titanDao.rollback();
+        throw new StorageException(status);
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.java
index 11355f3..76652e1 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.java
@@ -20,15 +20,8 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import static org.openecomp.sdc.be.dao.titan.TitanUtils.buildNotInPredicate;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
+import com.thinkaurelius.titan.graphdb.query.TitanPredicate;
+import fj.data.Either;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
@@ -42,19 +35,19 @@
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.resources.data.PolicyTypeData;
 import org.openecomp.sdc.be.resources.data.PropertyData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import com.thinkaurelius.titan.graphdb.query.TitanPredicate;
+import java.util.*;
+import java.util.stream.Collectors;
 
-import fj.data.Either;
+import static org.openecomp.sdc.be.dao.titan.TitanUtils.buildNotInPredicate;
 
 @Component("policy-type-operation")
 public class PolicyTypeOperation extends AbstractOperation implements IPolicyTypeOperation {
 
-    private static final Logger log = LoggerFactory.getLogger(PolicyTypeOperation.class.getName());
+    private static final Logger log = Logger.getLogger(PolicyTypeOperation.class.getName());
     private static final String CREATE_FLOW_CONTEXT = "CreatePolicyType";
     private static final String GET_FLOW_CONTEXT = "GetPolicyType";
 
@@ -62,6 +55,8 @@
     private PropertyOperation propertyOperation;
     @Autowired
     private DerivedFromOperation derivedFromOperation;
+    @Autowired
+    private OperationUtils operationUtils;
 
     @Override
     public Either<PolicyTypeDefinition, StorageOperationStatus> getLatestPolicyTypeByType(String type) {
@@ -94,18 +89,17 @@
     @Override
     public Either<PolicyTypeDefinition, StorageOperationStatus> updatePolicyType(PolicyTypeDefinition updatedPolicyType, PolicyTypeDefinition currPolicyType) {
         log.debug("updating policy type {}", updatedPolicyType.getType());
-        updatePolicyTypeData(updatedPolicyType, currPolicyType);
         return updatePolicyTypeOnGraph(updatedPolicyType, currPolicyType);
     }
 
     @Override
-    public Either<List<PolicyTypeDefinition>, StorageOperationStatus> getAllPolicyTypes(Set<String> excludedPolicyTypes) {
+    public List<PolicyTypeDefinition> getAllPolicyTypes(Set<String> excludedPolicyTypes) {
         Map<String, Map.Entry<TitanPredicate, Object>> predicateCriteria = buildNotInPredicate(GraphPropertiesDictionary.TYPE.getProperty(), excludedPolicyTypes);
         return titanGenericDao.getByCriteriaWithPredicate(NodeTypeEnum.PolicyType, predicateCriteria, PolicyTypeData.class)
                 .left()
                 .map(this::convertPolicyTypesToDefinition)
-                .right()
-                .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+                .left()
+                .on(operationUtils::onTitanOperationFailure);
     }
 
     private List<PolicyTypeDefinition> convertPolicyTypesToDefinition(List<PolicyTypeData> policiesTypes) {
@@ -116,7 +110,7 @@
     private Either<PolicyTypeData, StorageOperationStatus> addPolicyTypeToGraph(PolicyTypeDefinition policyTypeDef) {
         log.debug("Got policy type {}", policyTypeDef);
 
-        String ptUniqueId = UniqueIdBuilder.buildPolicyTypeUid(policyTypeDef.getType(), policyTypeDef.getVersion());
+        String ptUniqueId = UniqueIdBuilder.buildPolicyTypeUid(policyTypeDef.getType(), policyTypeDef.getVersion(), "policytype");
         PolicyTypeData policyTypeData = buildPolicyTypeData(policyTypeDef, ptUniqueId);
         log.debug("Before adding policy type to graph. policyTypeData = {}", policyTypeData);
         Either<PolicyTypeData, TitanOperationStatus> eitherPolicyTypeData = titanGenericDao.createNode(policyTypeData, PolicyTypeData.class);
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java
index 86e5b1b..5e900e4 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java
@@ -20,25 +20,22 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.StringJoiner;
-import java.util.function.Consumer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
+import com.fasterxml.jackson.core.ObjectCodec;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Maps;
+import com.google.gson.*;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import com.thinkaurelius.titan.core.TitanVertexProperty;
+import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
 import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
@@ -54,56 +51,41 @@
 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.IComplexDefaultValue;
-import org.openecomp.sdc.be.model.PropertyConstraint;
-import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
 import org.openecomp.sdc.be.model.operations.api.IPropertyOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
-import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType;
-import org.openecomp.sdc.be.model.tosca.constraints.GreaterOrEqualConstraint;
-import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint;
-import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint;
-import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint;
-import org.openecomp.sdc.be.model.tosca.constraints.LessThanConstraint;
-import org.openecomp.sdc.be.model.tosca.constraints.MinLengthConstraint;
-import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.*;
 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
-import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
-import org.openecomp.sdc.be.resources.data.DataTypeData;
-import org.openecomp.sdc.be.resources.data.PropertyData;
-import org.openecomp.sdc.be.resources.data.PropertyValueData;
-import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
-import org.openecomp.sdc.be.resources.data.UniqueIdData;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.be.resources.data.*;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
-import com.fasterxml.jackson.core.ObjectCodec;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-import com.thinkaurelius.titan.core.TitanVertex;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.function.Consumer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
-import fj.data.Either;
 
 @Component("property-operation")
 public class PropertyOperation extends AbstractOperation implements IPropertyOperation {
-
-	private TitanGenericDao titanGenericDao;
+	private static final String FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE = "Failed to fetch properties of data type {}";
+	private static final String DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS = "Data type {} cannot be found in graph. status is {}";
+	private static final String GOING_TO_EXECUTE_COMMIT_ON_GRAPH = "Going to execute commit on graph.";
+	private static final String GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH = "Going to execute rollback on graph.";
+	private static final String FAILED_TO_ASSOCIATE_RESOURCE_TO_PROPERTY_IN_GRAPH_STATUS_IS = "Failed to associate resource {} to property {} in graph. status is {}";
+	private static final String AFTER_ADDING_PROPERTY_TO_GRAPH = "After adding property to graph {}";
+	private static final String BEFORE_ADDING_PROPERTY_TO_GRAPH = "Before adding property to graph {}";
+	private static final String THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID = "The value {} of property from type {} is invalid";
 	private DerivedFromOperation derivedFromOperation;
-	
+    private static final String PROPERTY = "Property";
+    private static final String UPDATE_DATA_TYPE = "UpdateDataType";
+
 	public static void main(String[] args) {
 
 		List<Pattern> buildFunctionPatterns = buildFunctionPatterns();
@@ -124,14 +106,7 @@
 		this.derivedFromOperation = derivedFromOperation;
 	}
 
-	private static Logger log = LoggerFactory.getLogger(PropertyOperation.class.getName());
-
-	private static List<Pattern> functionPatterns = null;
-
-	static {
-
-		functionPatterns = buildFunctionPatterns();
-	}
+	private static Logger log = Logger.getLogger(PropertyOperation.class.getName());
 
 	/**
 	 * The value of functions is in a json format. Build pattern for each function name
@@ -160,7 +135,6 @@
 		PropertyDefinition propertyDefResult = new PropertyDefinition(propertyDataResult.getPropertyDataDefinition());
 		propertyDefResult.setConstraints(convertConstraints(propertyDataResult.getConstraints()));
 		propertyDefResult.setName(propertyName);
-//		propertyDefResult.setParentUniqueId(resourceId);
 
 		return propertyDefResult;
 	}
@@ -196,6 +170,8 @@
 
 	public static class PropertyConstraintDeserialiser implements JsonDeserializer<PropertyConstraint> {
 
+		private static final String THE_VALUE_OF_GREATER_THAN_CONSTRAINT_IS_NULL = "The value of GreaterThanConstraint is null";
+
 		@Override
 		public PropertyConstraint deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
 
@@ -231,7 +207,7 @@
 							}
 
 						} else {
-							log.warn("The value of GreaterThanConstraint is null");
+							log.warn(THE_VALUE_OF_GREATER_THAN_CONSTRAINT_IS_NULL);
 						}
 						break;
 					case GREATER_THAN:
@@ -241,7 +217,7 @@
 							propertyConstraint = new GreaterThanConstraint(asString);
 							break;
 						} else {
-							log.warn("The value of GreaterThanConstraint is null");
+							log.warn(THE_VALUE_OF_GREATER_THAN_CONSTRAINT_IS_NULL);
 						}
 						break;
 
@@ -272,7 +248,7 @@
 							log.debug("Before adding value to LessOrEqualConstraint object. value = {}", asString);
 							propertyConstraint = new LessOrEqualConstraint(asString);
 						} else {
-							log.warn("The value of GreaterThanConstraint is null");
+							log.warn(THE_VALUE_OF_GREATER_THAN_CONSTRAINT_IS_NULL);
 						}
 						break;
 
@@ -285,7 +261,7 @@
 									log.error("The valid values constraint content is invalid. value = {}", value);
 								} else {
 									ValidValuesConstraint vvConstraint = new ValidValuesConstraint();
-									List<String> validValues = new ArrayList<String>();
+									List<String> validValues = new ArrayList<>();
 									for (JsonElement jsonElement : rangeArray) {
 										String item = jsonElement.getAsString();
 										validValues.add(item);
@@ -321,60 +297,6 @@
 
 	}
 
-	public TitanOperationStatus addPropertiesToGraph(Map<String, PropertyDefinition> properties, String resourceId, Map<String, DataTypeDefinition> dataTypes) {
-
-		ResourceMetadataData resourceData = new ResourceMetadataData();
-		resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
-
-		if (properties != null) {
-			for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
-
-				String propertyName = entry.getKey();
-				PropertyDefinition propertyDefinition = entry.getValue();
-
-				StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes);
-				if (validateAndUpdateProperty != StorageOperationStatus.OK) {
-					log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty);
-					return TitanOperationStatus.ILLEGAL_ARGUMENT;
-				}
-
-				Either<PropertyData, TitanOperationStatus> addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
-
-				if (addPropertyToGraph.isRight()) {
-					return addPropertyToGraph.right().value();
-				}
-			}
-		}
-
-		return TitanOperationStatus.OK;
-
-	}
-
-	public TitanOperationStatus addPropertiesToGraph(TitanVertex metadataVertex, Map<String, PropertyDefinition> properties, Map<String, DataTypeDefinition> dataTypes, String resourceId) {
-
-		if (properties != null) {
-			for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
-
-				String propertyName = entry.getKey();
-				PropertyDefinition propertyDefinition = entry.getValue();
-
-				StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes);
-				if (validateAndUpdateProperty != StorageOperationStatus.OK) {
-					log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty);
-					return TitanOperationStatus.ILLEGAL_ARGUMENT;
-				}
-
-				TitanOperationStatus addPropertyToGraph = addPropertyToGraphByVertex(metadataVertex, propertyName, propertyDefinition, resourceId);
-
-				if (!addPropertyToGraph.equals(TitanOperationStatus.OK)) {
-					return addPropertyToGraph;
-				}
-			}
-		}
-
-		return TitanOperationStatus.OK;
-
-	}
 
 	public Either<PropertyData, StorageOperationStatus> addProperty(String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
 
@@ -408,14 +330,12 @@
 				return StorageOperationStatus.INVALID_TYPE;
 			}
 
-			StorageOperationStatus status = validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes);
-
-			return status;
+            return validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes);
 
 		}
 		String innerType = null;
 
-		Either<String, TitanOperationStatus> checkInnerType = getInnerType(type, () -> propertyDefinition.getSchema());
+		Either<String, TitanOperationStatus> checkInnerType = getInnerType(type, propertyDefinition::getSchema);
 		if (checkInnerType.isRight()) {
 			return StorageOperationStatus.INVALID_TYPE;
 		}
@@ -424,8 +344,8 @@
 		log.trace("After validating property type {}", propertyType);
 
 		boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
-		if (false == isValidProperty) {
-			log.info("The value {} of property from type {} is invalid", value, type);
+		if (!isValidProperty) {
+			log.info(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, type);
 			return StorageOperationStatus.INVALID_VALUE;
 		}
 
@@ -434,7 +354,7 @@
 		if (isEmptyValue(value)) {
 			log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE);
 			propertyDefinition.setDefaultValue(EMPTY_VALUE);
-		} else if (false == isEmptyValue(value)) {
+		} else if (!isEmptyValue(value)) {
 			String convertedValue = converter.convert(value, innerType, dataTypes);
 			propertyDefinition.setDefaultValue(convertedValue);
 		}
@@ -451,21 +371,21 @@
 		propertyDefinition.setUniqueId(UniqueIdBuilder.buildComponentPropertyUniqueId(resourceId, propertyName));
 		PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
 
-		log.debug("Before adding property to graph {}", propertyData);
+		log.debug(BEFORE_ADDING_PROPERTY_TO_GRAPH, propertyData);
 		Either<PropertyData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class);
-		log.debug("After adding property to graph {}", propertyData);
+		log.debug(AFTER_ADDING_PROPERTY_TO_GRAPH, propertyData);
 		if (createNodeResult.isRight()) {
 			TitanOperationStatus operationStatus = createNodeResult.right().value();
 			log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
 			return Either.right(operationStatus);
 		}
 
-		Map<String, Object> props = new HashMap<String, Object>();
+		Map<String, Object> props = new HashMap<>();
 		props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
 		Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData, propertyData, GraphEdgeLabels.PROPERTY, props);
 		if (createRelResult.isRight()) {
 			TitanOperationStatus operationStatus = createNodeResult.right().value();
-			log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, propertyName, operationStatus);
+			log.error(FAILED_TO_ASSOCIATE_RESOURCE_TO_PROPERTY_IN_GRAPH_STATUS_IS, resourceId, propertyName, operationStatus);
 			return Either.right(operationStatus);
 		}
 
@@ -480,21 +400,21 @@
 		propertyDefinition.setUniqueId(UniqueIdBuilder.buildComponentPropertyUniqueId(resourceId, propertyName));
 		PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
 
-		log.debug("Before adding property to graph {}", propertyData);
+		log.debug(BEFORE_ADDING_PROPERTY_TO_GRAPH, propertyData);
 		Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData);
-		log.debug("After adding property to graph {}", propertyData);
+		log.debug(AFTER_ADDING_PROPERTY_TO_GRAPH, propertyData);
 		if (createNodeResult.isRight()) {
 			TitanOperationStatus operationStatus = createNodeResult.right().value();
 			log.error("Failed to add property {} to graph. status is ", propertyName, operationStatus);
 			return operationStatus;
 		}
 
-		Map<String, Object> props = new HashMap<String, Object>();
+		Map<String, Object> props = new HashMap<>();
 		props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
 		TitanVertex propertyVertex = createNodeResult.left().value();
 		TitanOperationStatus createRelResult = titanGenericDao.createEdge(metadataVertex, propertyVertex, GraphEdgeLabels.PROPERTY, props);
 		if (!createRelResult.equals(TitanOperationStatus.OK)) {
-			log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, propertyName, createRelResult);
+			log.error(FAILED_TO_ASSOCIATE_RESOURCE_TO_PROPERTY_IN_GRAPH_STATUS_IS, resourceId, propertyName, createRelResult);
 			return createRelResult;
 		}
 
@@ -506,20 +426,6 @@
 		return titanGenericDao;
 	}
 
-	// public Either<PropertyData, StorageOperationStatus>
-	// deletePropertyFromGraphFromBl(String propertyId) {
-	//
-	// }
-
-	public Either<PropertyData, StorageOperationStatus> deleteProperty(String propertyId) {
-		Either<PropertyData, TitanOperationStatus> either = deletePropertyFromGraph(propertyId);
-		if (either.isRight()) {
-			StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value());
-			return Either.right(storageStatus);
-		}
-		return Either.left(either.left().value());
-	}
-
 	public Either<PropertyData, TitanOperationStatus> deletePropertyFromGraph(String propertyId) {
 		log.debug("Before deleting property from graph {}", propertyId);
 		return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
@@ -601,17 +507,17 @@
 		PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
 
 		if (log.isDebugEnabled())
-			log.debug("Before adding property to graph {}", propertyData);
+			log.debug(BEFORE_ADDING_PROPERTY_TO_GRAPH, propertyData);
 		Either<PropertyData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class);
 		if (log.isDebugEnabled())
-			log.debug("After adding property to graph {}", propertyData);
+			log.debug(AFTER_ADDING_PROPERTY_TO_GRAPH, propertyData);
 		if (createNodeResult.isRight()) {
 			TitanOperationStatus operationStatus = createNodeResult.right().value();
 			log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
 			return Either.right(operationStatus);
 		}
 
-		Map<String, Object> props = new HashMap<String, Object>();
+		Map<String, Object> props = new HashMap<>();
 		props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
 
 		UniqueIdData uniqueIdData = new UniqueIdData(nodeType, uniqueId);
@@ -619,7 +525,7 @@
 		Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(uniqueIdData, propertyData, GraphEdgeLabels.PROPERTY, props);
 		if (createRelResult.isRight()) {
 			TitanOperationStatus operationStatus = createNodeResult.right().value();
-			log.error("Failed to associate resource {} to property {} in graph. status is {}", uniqueId, propertyName, operationStatus);
+			log.error(FAILED_TO_ASSOCIATE_RESOURCE_TO_PROPERTY_IN_GRAPH_STATUS_IS, uniqueId, propertyName, operationStatus);
 			return Either.right(operationStatus);
 		}
 
@@ -629,7 +535,7 @@
 
 	public Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId) {
 
-		Map<String, PropertyDefinition> resourceProps = new HashMap<String, PropertyDefinition>();
+		Map<String, PropertyDefinition> resourceProps = new HashMap<>();
 
 		Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property,
 				PropertyData.class);
@@ -662,6 +568,139 @@
                 .right()
                 .bind(err -> err == StorageOperationStatus.OK ? Either.left(Collections.emptyMap()) : Either.right(err));
     }
+    
+    public Either<Map<String, PropertyData>, TitanOperationStatus> mergePropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId, Map<String, PropertyDefinition> newProperties) {
+        Either<Map<String, PropertyDefinition>, TitanOperationStatus> oldPropertiesRes = findPropertiesOfNode(nodeType, uniqueId);
+        
+        Map<String, PropertyDefinition> reallyNewProperties;
+        Map<String, PropertyData> unchangedPropsData;
+        
+        if (oldPropertiesRes.isRight()) {
+            TitanOperationStatus err  = oldPropertiesRes.right().value();
+            if (err == TitanOperationStatus.NOT_FOUND) {
+                reallyNewProperties = newProperties;
+                unchangedPropsData = Collections.emptyMap();
+            }
+            else {
+                return Either.right(err);
+            }
+        }
+        else {
+            Map<String, PropertyDefinition> oldProperties = oldPropertiesRes.left().value();
+            reallyNewProperties = collectReallyNewProperties(newProperties, oldProperties);
+            
+            for(Entry<String, PropertyDefinition> oldEntry: oldProperties.entrySet()) {
+                String key = oldEntry.getKey();
+                PropertyDefinition newPropDef = newProperties != null? newProperties.get(key): null;
+                PropertyDefinition oldPropDef = oldEntry.getValue();
+
+                TitanOperationStatus status = updateOldProperty(newPropDef, oldPropDef);
+                if (status != TitanOperationStatus.OK) {
+                    return Either.right(status);
+                }
+            }
+            unchangedPropsData = oldProperties.entrySet().stream()
+                                        .collect(Collectors.toMap(Entry::getKey, e-> new PropertyData(e.getValue(), null)));
+        }
+            
+            
+        // add other properties
+        return addPropertiesToElementType(nodeType, uniqueId, reallyNewProperties, unchangedPropsData);
+    }
+
+    /**
+     * @param newProperties
+     * @param oldProperties
+     * @return
+     */
+    private Map<String, PropertyDefinition> collectReallyNewProperties(Map<String, PropertyDefinition> newProperties, Map<String, PropertyDefinition> oldProperties) {
+        return newProperties != null? newProperties.entrySet().stream()
+                                        .filter(entry -> !oldProperties.containsKey(entry.getKey()))
+                                        .collect(Collectors.toMap(Entry::getKey, Entry::getValue) ): null;
+    }
+
+    /**
+     * @param newPropDef
+     * @param oldPropDef
+     */
+    private TitanOperationStatus updateOldProperty(PropertyDefinition newPropDef, PropertyDefinition oldPropDef) {
+        if (!isUpdateAllowed(newPropDef, oldPropDef)) {
+            return TitanOperationStatus.MATCH_NOT_FOUND;
+        }
+        
+        if (isUpdateRequired(newPropDef, oldPropDef)) {
+            modifyOldPropByNewOne(newPropDef, oldPropDef);
+            
+            List<PropertyConstraint> constraints = oldPropDef.getConstraints();
+            PropertyData node = new PropertyData(oldPropDef, convertConstraintsToString(constraints));
+            Either<PropertyData, TitanOperationStatus> updateResult = titanGenericDao.updateNode(node, PropertyData.class);
+            
+            if (updateResult.isRight()) {
+                return updateResult.right().value();
+            }
+        }
+        
+        return TitanOperationStatus.OK;
+    }
+
+    /**
+     * @param newPropDef
+     * @param oldPropDef
+     */
+    private boolean isUpdateAllowed(PropertyDefinition newPropDef, PropertyDefinition oldPropDef) {
+        if (newPropDef == null) {
+            log.error("#mergePropertiesAssociatedToNode - Failed due attempt to delete the property with id {}", oldPropDef.getUniqueId());
+            return false;
+        }
+        
+        // If the property type is missing it's something that we could want to fix 
+        if ( oldPropDef.getType() != null && !oldPropDef.getType().equals(newPropDef.getType())) {
+            log.error("#mergePropertiesAssociatedToNode - Failed due attempt to change type of the property with id {}", oldPropDef.getUniqueId());
+            return false;
+        }
+        
+        return true;
+    }
+
+    /**
+     * Update only fields which modification is permitted.
+     * @param newPropDef
+     * @param oldPropDef
+     */
+    private void modifyOldPropByNewOne(PropertyDefinition newPropDef, PropertyDefinition oldPropDef) {
+        oldPropDef.setDefaultValue(newPropDef.getDefaultValue());
+        oldPropDef.setDescription(newPropDef.getDescription());
+        oldPropDef.setRequired(newPropDef.isRequired());
+
+        // Type is updated to fix possible null type issue in TITAN DB
+        oldPropDef.setType(newPropDef.getType());
+    }
+
+
+    private boolean isUpdateRequired(PropertyDefinition newPropDef, PropertyDefinition oldPropDef) {
+        return !StringUtils.equals(oldPropDef.getDefaultValue(), newPropDef.getDefaultValue()) ||
+            !StringUtils.equals(oldPropDef.getDescription(), newPropDef.getDescription()) ||
+            oldPropDef.isRequired() != newPropDef.isRequired();
+    }
+
+    /**
+     * Adds newProperties and returns in case of success (left part of Either) 
+     * map of all properties i. e. added ones and contained in unchangedPropsData
+     * @param nodeType
+     * @param uniqueId
+     * @param newProperties
+     * @param unchangedPropsData
+     * @return
+     */
+    private Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToElementType(NodeTypeEnum nodeType, String uniqueId, Map<String, PropertyDefinition> newProperties, Map<String, PropertyData> unchangedPropsData) {
+        return addPropertiesToElementType(uniqueId, nodeType, newProperties)
+                .left()
+                .map(m -> { 
+                    m.putAll(unchangedPropsData);
+                    return m;
+                 });
+    }
+
 
 	public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deleteAllPropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) {
 
@@ -695,50 +734,6 @@
 		return Either.left(value);
 	}
 
-	/**
-	 * 
-	 * 
-	 * @param nodeType
-	 * @param uniqueId
-	 * @param properties
-	 * @return
-	 */
-	protected TitanOperationStatus findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId, List<PropertyDefinition> properties) {
-
-		Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property,
-				PropertyData.class);
-
-		if (childrenNodes.isRight()) {
-			TitanOperationStatus status = childrenNodes.right().value();
-			if (status == TitanOperationStatus.NOT_FOUND) {
-				status = TitanOperationStatus.OK;
-			}
-			return status;
-		}
-
-		List<ImmutablePair<PropertyData, GraphEdge>> values = childrenNodes.left().value();
-		if (values != null) {
-
-			for (ImmutablePair<PropertyData, GraphEdge> immutablePair : values) {
-				GraphEdge edge = immutablePair.getValue();
-				String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
-				if (log.isDebugEnabled())
-					log.debug("Property {} is associated to node {}", propertyName, uniqueId);
-				PropertyData propertyData = immutablePair.getKey();
-				PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId);
-				//Adds parent property to List if it hasn't been overrided in one of the children
-				if(!properties.stream().filter(p -> p.getName().equals(propertyDefinition.getName())).findAny().isPresent()){
-					properties.add(propertyDefinition);
-				}
-
-				if (log.isTraceEnabled())
-					log.trace("findPropertiesOfNode - property {} associated to node {}", propertyDefinition, uniqueId);
-			}
-
-		}
-
-		return TitanOperationStatus.OK;
-	}
 /**
  * Checks existence of a property with the same name belonging to the same resource
  * or existence of property with the same name and different type (including derived from hierarchy)
@@ -763,73 +758,10 @@
 		return result;
 	}
 
-	/**
-	 * add property to resource instance
-	 * 
-	 * @param innerType
-	 *            TODO // * @param resourceInstanceProperty // * @param resourceInstanceId // * @param index
-	 * 
-	 * @return
-	 */
-	/*
-	 * public Either<PropertyValueData, TitanOperationStatus> addPropertyToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index) {
-	 * 
-	 * Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
-	 * 
-	 * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
-	 * 
-	 * String propertyId = resourceInstanceProperty.getUniqueId(); Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
-	 * 
-	 * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
-	 * 
-	 * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) {
-	 * 
-	 * PropertyData propertyData = findPropertyDefRes.left().value(); ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value();
-	 * 
-	 * ImmutablePair<TitanOperationStatus, String> isPropertyValueExists = findPropertyValue(resourceInstanceId, propertyId); if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { log.debug("The property " + propertyId +
-	 * " already added to the resource instance " + resourceInstanceId); resourceInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight ()); Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance =
-	 * updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId); if (updatePropertyOfResourceInstance.isRight()) { BeEcompErrorManager.getInstance().logInternalFlowError( "UpdatePropertyValueOnComponentInstance",
-	 * "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); return Either.right(updatePropertyOfResourceInstance.right().value()); } return
-	 * Either.left(updatePropertyOfResourceInstance.left().value()); }
-	 * 
-	 * if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) { 
-	 * log.debug("After finding property value of {} on componenet instance {}", propertyId, resourceInstanceId); 
-	 * return Either.right(isPropertyValueExists.getLeft()); }
-	 * 
-	 * String propertyType = propertyData.getPropertyDataDefinition().getType(); String value = resourceInstanceProperty.getValue(); Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value);
-	 * 
-	 * String newValue = value; if (isValid.isRight()) { Boolean res = isValid.right().value(); if (res == false) { return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } } else { Object object = isValid.left().value(); if (object != null) {
-	 * newValue = object.toString(); } }
-	 * 
-	 * String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid( resourceInstanceData.getUniqueId(), index); PropertyValueData propertyValueData = new PropertyValueData(); propertyValueData.setUniqueId(uniqueId);
-	 * propertyValueData.setValue(newValue);
-	 * 
-	 * ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance().
-	 * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } addRulesToNewPropertyValue(propertyValueData,
-	 * resourceInstanceProperty, resourceInstanceId);
-	 * 
-	 * log.debug("Before adding property value to graph {}", propertyValueData); 
-	 * Either<PropertyValueData, TitanOperationStatus> createNodeResult = titanGenericDao .createNode(propertyValueData, PropertyValueData.class);
-	 * log.debug("After adding property value to graph {}", propertyValueData);
-	 * 
-	 * Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao .createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null);
-	 * 
-	 * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate property value " + uniqueId + " to property " + propertyId +
-	 * " in graph. status is " + operationStatus); return Either.right(operationStatus); }
-	 * 
-	 * createRelResult = titanGenericDao .createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null);
-	 * 
-	 * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate resource instance " + resourceInstanceId + " property value " + uniqueId +
-	 * " in graph. status is " + operationStatus); return Either.right(operationStatus); }
-	 * 
-	 * return Either.left(createNodeResult.left().value()); } else { log.error("property value already exists."); return Either.right(TitanOperationStatus.ALREADY_EXIST); }
-	 * 
-	 * }
-	 */
 	public ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
 
-		if (rules == null || rules.isEmpty() == true) {
-			return new ImmutablePair<String, Boolean>(null, true);
+		if (rules == null || rules.isEmpty()) {
+			return new ImmutablePair<>(null, true);
 		}
 
 		for (PropertyRule rule : rules) {
@@ -837,8 +769,8 @@
 			Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
 			if (updateResult.isRight()) {
 				Boolean status = updateResult.right().value();
-				if (status == false) {
-					return new ImmutablePair<String, Boolean>(value, status);
+				if (!status) {
+					return new ImmutablePair<>(value, status);
 				}
 			} else {
 				String newValue = null;
@@ -850,7 +782,7 @@
 			}
 		}
 
-		return new ImmutablePair<String, Boolean>(null, true);
+		return new ImmutablePair<>(null, true);
 	}
 
 	public void addRulesToNewPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
@@ -873,7 +805,7 @@
 		// graph.
 		// Update could be done on one level only, thus we can use this
 		// operation to avoid migration.
-		if (path == null || path.isEmpty() == true) {
+		if (path == null || path.isEmpty()) {
 			path = new ArrayList<>();
 			path.add(resourceInstanceId);
 		}
@@ -900,7 +832,7 @@
 		if (getAllRes.isRight()) {
 			TitanOperationStatus status = getAllRes.right().value();
 			log.trace("After fetching all properties of resource instance {}. Status is {}", resourceInstanceId, status);
-			return new ImmutablePair<TitanOperationStatus, String>(status, null);
+			return new ImmutablePair<>(status, null);
 		}
 
 		List<ComponentInstanceProperty> list = getAllRes.left().value();
@@ -911,63 +843,14 @@
 				log.trace("Go over property {} under resource instance {}. valueUniqueId = {}", propertyUniqueId, resourceInstanceId, valueUniqueUid);
 				if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) {
 					log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId);
-					return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid);
+					return new ImmutablePair<>(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid);
 				}
 			}
 		}
 
-		return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.NOT_FOUND, null);
+		return new ImmutablePair<>(TitanOperationStatus.NOT_FOUND, null);
 	}
 
-	/**
-	 * update value of property on resource instance
-	 * 
-	 * @param resourceInstanceProperty
-	 * @param resourceInstanceId
-	 * @return
-	 */
-	/*
-	 * public Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
-	 * 
-	 * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// /// Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder
-	 * .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
-	 * 
-	 * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
-	 * 
-	 * String propertyId = resourceInstanceProperty.getUniqueId(); Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
-	 * 
-	 * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); return Either.right(status); }
-	 * 
-	 * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) { return Either.right(TitanOperationStatus.INVALID_ID); } else { Either<PropertyValueData, TitanOperationStatus> findPropertyValueRes =
-	 * titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, PropertyValueData.class); if (findPropertyValueRes.isRight()) { TitanOperationStatus status = findPropertyValueRes.right().value(); if
-	 * (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
-	 * 
-	 * String value = resourceInstanceProperty.getValue();
-	 * 
-	 * Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property,
-	 * PropertyData.class);
-	 * 
-	 * if (child.isRight()) { TitanOperationStatus status = child.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
-	 * 
-	 * PropertyData propertyData = child.left().value().left; String propertyType = propertyData.getPropertyDataDefinition().getType();
-	 * 
-	 * log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType);
-	 * 
-	 * Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value);
-	 * 
-	 * String newValue = value; if (isValid.isRight()) { Boolean res = isValid.right().value(); if (res == false) { return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } } else { Object object = isValid.left().value(); if (object != null) {
-	 * newValue = object.toString(); } } PropertyValueData propertyValueData = findPropertyValueRes.left().value(); log.debug("Going to update property value from " + propertyValueData.getValue() + " to " + newValue);
-	 * propertyValueData.setValue(newValue);
-	 * 
-	 * ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance().
-	 * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } updateRulesInPropertyValue(propertyValueData,
-	 * resourceInstanceProperty, resourceInstanceId);
-	 * 
-	 * Either<PropertyValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class); if (updateRes.isRight()) { TitanOperationStatus status = updateRes.right().value(); return
-	 * Either.right(status); } else { return Either.left(updateRes.left().value()); } }
-	 * 
-	 * }
-	 */
 
 	public void updateRulesInPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
 
@@ -998,7 +881,7 @@
 
 		List<PropertyRule> mergedRules = new ArrayList<>();
 
-		if (newRules == null || newRules.isEmpty() == true) {
+		if (newRules == null || newRules.isEmpty()) {
 			return currentRules;
 		}
 
@@ -1021,7 +904,7 @@
 
 	private PropertyRule findRuleInList(PropertyRule rule, List<PropertyRule> rules) {
 
-		if (rules == null || rules.isEmpty() == true || rule.getRule() == null || rule.getRule().isEmpty() == true) {
+		if (rules == null || rules.isEmpty() || rule.getRule() == null || rule.getRule().isEmpty()) {
 			return null;
 		}
 
@@ -1031,7 +914,7 @@
 				continue;
 			}
 			boolean equals = propertyRule.compareRule(rule);
-			if (equals == true) {
+			if (equals) {
 				foundRule = propertyRule;
 				break;
 			}
@@ -1052,48 +935,6 @@
 
 	}
 
-	/*
-	 * public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, boolean inTransaction) {
-	 * 
-	 * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// ///
-	 * 
-	 * Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
-	 * 
-	 * try {
-	 * 
-	 * Either<PropertyValueData, TitanOperationStatus> eitherStatus = this .addPropertyToResourceInstance(resourceInstanceProperty, resourceInstanceId, index);
-	 * 
-	 * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result =
-	 * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value();
-	 * 
-	 * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty);
-	 * 
-	 * log.debug("The returned ResourceInstanceProperty is  {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } }
-	 * 
-	 * finally { if (false == inTransaction) { if (result == null || result.isRight()) { log.error("Going to execute rollback on graph."); titanGenericDao.rollback(); } else { log.debug("Going to execute commit on graph."); titanGenericDao.commit();
-	 * } } }
-	 * 
-	 * }
-	 * 
-	 * public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean inTransaction) {
-	 * 
-	 * Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
-	 * 
-	 * try { //TODO: verify validUniqueId exists Either<PropertyValueData, TitanOperationStatus> eitherStatus = this .updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId);
-	 * 
-	 * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result =
-	 * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value();
-	 * 
-	 * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty);
-	 * 
-	 * log.debug("The returned ResourceInstanceProperty is  {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } }
-	 * 
-	 * finally { if (false == inTransaction) { if (result == null || result.isRight()) { log.error("Going to execute rollback on graph."); titanGenericDao.rollback(); } else { log.debug("Going to execute commit on graph."); titanGenericDao.commit();
-	 * } } }
-	 * 
-	 * }
-	 */
-
 	public Either<PropertyValueData, TitanOperationStatus> removePropertyOfResourceInstance(String propertyValueUid, String resourceInstanceId) {
 
 		Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
@@ -1161,12 +1002,12 @@
 		}
 
 		finally {
-			if (false == inTransaction) {
+			if (!inTransaction) {
 				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
+					log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
 					titanGenericDao.rollback();
 				} else {
-					log.debug("Going to execute commit on graph.");
+					log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
 					titanGenericDao.commit();
 				}
 			}
@@ -1256,7 +1097,7 @@
 	public ImmutablePair<String, Boolean> isPropertyInnerTypeValid(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
 
 		if (property == null) {
-			return new ImmutablePair<String, Boolean>(null, false);
+			return new ImmutablePair<>(null, false);
 		}
 
 		SchemaDefinition schema;
@@ -1274,22 +1115,16 @@
 			DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
 			if (dataTypeDefinition == null) {
 				log.debug("The inner type {} is not a data type.", innerType);
-				return new ImmutablePair<String, Boolean>(innerType, false);
+				return new ImmutablePair<>(innerType, false);
 			} else {
 				log.debug("The inner type {} is a data type. Data type definition is {}", innerType, dataTypeDefinition);
 			}
 		}
 
-		return new ImmutablePair<String, Boolean>(innerType, true);
+		return new ImmutablePair<>(innerType, true);
 	}
 
 	private boolean isValidComplexValue(DataTypeDefinition foundDt, String value, Map<String, DataTypeDefinition> dataTypes) {
-		/*
-		 * Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value();
-		 * return false; }
-		 * 
-		 * Map<String, DataTypeDefinition> allDataTypes = allDataTypesRes.left().value();
-		 */
 		ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter.validateAndUpdate(value, foundDt, dataTypes);
 
 		log.trace("The result after validating complex value of type {} is {}", foundDt.getName(), validateAndUpdate);
@@ -1318,7 +1153,7 @@
 		}
 
 		List<ImmutablePair<TitanVertex, Edge>> list = propertyImplNodes.left().value();
-		if (list == null || true == list.isEmpty()) {
+		if (list == null || list.isEmpty()) {
 			return Either.right(TitanOperationStatus.NOT_FOUND);
 		}
 
@@ -1486,7 +1321,7 @@
 					continue;
 				}
 				// check that the rule starts with correct component instance id
-				if (false == checkFirstItem(firstCompInstance, rule.getFirstToken())) {
+				if (!checkFirstItem(firstCompInstance, rule.getFirstToken())) {
 					continue;
 				}
 
@@ -1664,9 +1499,9 @@
 	 */
 	private Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType(String uniqueId, List<PropertyDefinition> properties) {
 
-		Map<String, PropertyData> propertiesData = new HashMap<String, PropertyData>();
+		Map<String, PropertyData> propertiesData = new HashMap<>();
 
-		if (properties != null && false == properties.isEmpty()) {
+		if (properties != null && !properties.isEmpty()) {
 			for (PropertyDefinition propertyDefinition : properties) {
 				String propertyName = propertyDefinition.getName();
 
@@ -1677,7 +1512,7 @@
 					return Either.right(validPropertyType.right().value());
 				}
 				Boolean isValid = validPropertyType.left().value();
-				if (isValid == null || isValid.booleanValue() == false) {
+				if (isValid == null || !isValid.booleanValue()) {
 					log.debug("Data type {} contains invalid property type {}", uniqueId, propertyType);
 					return Either.right(TitanOperationStatus.INVALID_TYPE);
 				}
@@ -1727,7 +1562,7 @@
 
 		if (dataTypesRes.isRight()) {
 			TitanOperationStatus status = dataTypesRes.right().value();
-			log.debug("Data type {} cannot be found in graph. status is {}", uniqueId, status);
+			log.debug(DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status);
 			return Either.right(status);
 		}
 
@@ -1736,7 +1571,7 @@
 
 		TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
 		if (propertiesStatus != TitanOperationStatus.OK) {
-			log.error("Failed to fetch properties of data type {}", uniqueId);
+			log.error(FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE, uniqueId);
 			return Either.right(propertiesStatus);
 		}
 
@@ -1785,7 +1620,7 @@
 			}
 		} else {
 			Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
-			if (properties != null && properties.isEmpty() == false) {
+			if (properties != null && !properties.isEmpty()) {
 				List<PropertyDefinition> listOfProps = new ArrayList<>();
 
 				for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
@@ -1823,12 +1658,12 @@
 				return result;
 			}
 		} finally {
-			if (false == inTransaction) {
+			if (!inTransaction) {
 				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
+					log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
 					titanGenericDao.rollback();
 				} else {
-					log.debug("Going to execute commit on graph.");
+					log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
 					titanGenericDao.commit();
 				}
 			}
@@ -1863,12 +1698,12 @@
 
 			return result;
 		} finally {
-			if (false == inTransaction) {
+			if (!inTransaction) {
 				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
+					log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
 					titanGenericDao.rollback();
 				} else {
-					log.debug("Going to execute commit on graph.");
+					log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
 					titanGenericDao.commit();
 				}
 			}
@@ -1907,12 +1742,12 @@
 
 			return result;
 		} finally {
-			if (false == inTransaction) {
+			if (!inTransaction) {
 				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
+					log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
 					titanGenericDao.rollback();
 				} else {
-					log.debug("Going to execute commit on graph.");
+					log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
 					titanGenericDao.commit();
 				}
 			}
@@ -1926,7 +1761,7 @@
 
 		if (dataTypesRes.isRight()) {
 			TitanOperationStatus status = dataTypesRes.right().value();
-			log.debug("Data type {} cannot be found in graph. status is {}", uniqueId, status);
+			log.debug(DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status);
 			return Either.right(status);
 		}
 
@@ -1935,7 +1770,7 @@
 
 		TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
 		if (propertiesStatus != TitanOperationStatus.OK) {
-			log.error("Failed to fetch properties of data type {}", uniqueId);
+			log.error(FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE, uniqueId);
 			return Either.right(propertiesStatus);
 		}
 
@@ -1952,9 +1787,7 @@
 	protected DataTypeDefinition convertDTDataToDTDefinition(DataTypeData dataTypeData) {
 		log.debug("The object returned after create data type is {}", dataTypeData);
 
-		DataTypeDefinition dataTypeDefResult = new DataTypeDefinition(dataTypeData.getDataTypeDataDefinition());
-
-		return dataTypeDefResult;
+        return new DataTypeDefinition(dataTypeData.getDataTypeDataDefinition());
 	}
 
 	private Either<Boolean, TitanOperationStatus> isValidPropertyType(String propertyType) {
@@ -1965,8 +1798,7 @@
 
 		ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(propertyType);
 		if (toscaPropertyType == null) {
-			Either<Boolean, TitanOperationStatus> definedInDataTypes = isDefinedInDataTypes(propertyType);
-			return definedInDataTypes;
+            return isDefinedInDataTypes(propertyType);
 		} else {
 			return Either.left(true);
 		}
@@ -2058,7 +1890,7 @@
 
 		if (dataTypesRes.isRight()) {
 			TitanOperationStatus status = dataTypesRes.right().value();
-			log.debug("Data type {} cannot be found in graph. status is {}", uniqueId, status);
+			log.debug(DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status);
 			return Either.right(status);
 		}
 
@@ -2067,7 +1899,7 @@
 
 		TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
 		if (propertiesStatus != TitanOperationStatus.OK) {
-			log.error("Failed to fetch properties of data type {}", uniqueId);
+			log.error(FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE, uniqueId);
 			return Either.right(propertiesStatus);
 		}
 
@@ -2125,7 +1957,7 @@
 
 		ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
 
-		return getInnerType(type, () -> propDataDef.getSchema());
+		return getInnerType(type, propDataDef::getSchema);
 	}
 
 	public Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypeNodes() {
@@ -2150,7 +1982,7 @@
 				DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
 				ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
 				if (Boolean.FALSE.equals(validateResult.right)) {
-					log.debug("The value {} of property from type {} is invalid", value, propertyType);
+					log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, propertyType);
 					return Either.right(false);
 				}
 				JsonElement jsonElement = validateResult.left;
@@ -2160,7 +1992,7 @@
 			log.trace("before validating property type {}", propertyType);
 			boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
 			if (!isValidProperty) {
-				log.debug("The value {} of property from type {} is invalid", value, type);
+				log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, type);
 				return Either.right(false);
 			}
 		}
@@ -2197,7 +2029,7 @@
 		Either<T, StorageOperationStatus> derivedFrom;
 		while ((derivedFrom = derivedFromOperation.getDerivedFromChild(currentNodeUid, nodeType, clazz)).isLeft()) {
 			currentNodeUid = derivedFrom.left().value().getUniqueId();
-			TitanOperationStatus titanOperationStatus = fillProperties(currentNodeUid, nodeType, accumulatedProps::addAll);
+			TitanOperationStatus titanOperationStatus = fillPropertiesList(currentNodeUid, nodeType, accumulatedProps::addAll);
 			if (titanOperationStatus != TitanOperationStatus.OK) {
 				log.debug("failed to fetch properties for type {} with id {}", nodeType, currentNodeUid);
 				return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus));
@@ -2214,28 +2046,30 @@
 	/*
 	 * @Override public PropertyOperation getPropertyOperation() { return this; }
 	 */
-	protected TitanOperationStatus fillProperties(String uniqueId, NodeTypeEnum nodeType, Consumer<List<PropertyDefinition>> propertySetter) {
-		Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(nodeType, uniqueId);
-		if (findPropertiesOfNode.isRight()) {
-			TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
-			log.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
-			if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
-				return TitanOperationStatus.OK;
-			} else {
-				return titanOperationStatus;
-			}
-		} else {
-			Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
-
-			if (properties != null) {
-				List<PropertyDefinition> propertiesAsList = properties.entrySet().stream().map(p -> p.getValue()).collect(Collectors.toList());
-				propertySetter.accept(propertiesAsList);
-			}
-
-			return TitanOperationStatus.OK;
+    public TitanOperationStatus fillPropertiesList(String uniqueId, NodeTypeEnum nodeType, Consumer<List<PropertyDefinition>> propertySetter) {
+		Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesRes = findPropertiesifExist(uniqueId, nodeType);
+		if (findPropertiesRes.isRight()) {
+			return findPropertiesRes.right().value();
 		}
+		Map<String, PropertyDefinition> properties = findPropertiesRes.left().value();
+		if (properties != null) {
+		List<PropertyDefinition> propertiesAsList = properties.entrySet().stream().map(Entry::getValue).collect(Collectors.toList());
+			propertySetter.accept(propertiesAsList);
+		}
+		return TitanOperationStatus.OK;
 	}
 
+	Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesifExist(String uniqueId, NodeTypeEnum nodeType){
+		Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(nodeType, uniqueId);
+		if (findPropertiesOfNode.isRight()) {
+			log.debug("After looking for properties of vertex {}. status is {}", uniqueId, findPropertiesOfNode.right().value());
+			if(findPropertiesOfNode.right().value() == TitanOperationStatus.NOT_FOUND)
+				return Either.left(Maps.newHashMap());
+			return findPropertiesOfNode;
+		}
+		return findPropertiesOfNode;
+		}
+	
 	/**
 	 * add properties to element type.
 	 * 
@@ -2248,7 +2082,7 @@
 	 */
 	protected Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map<String, PropertyDefinition> propertiesMap) {
 
-		Map<String, PropertyData> propertiesData = new HashMap<String, PropertyData>();
+		Map<String, PropertyData> propertiesData = new HashMap<>();
 
 		if (propertiesMap != null) {
 
@@ -2277,7 +2111,7 @@
 		if (properties == null) {
 			propMap = null;
 		} else {
-			propMap = properties.stream().collect(Collectors.toMap(propDef -> propDef.getName(), propDef -> propDef));
+			propMap = properties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, propDef -> propDef));
 		}
 		return addPropertiesToElementType(uniqueId, elementType, propMap);
 	}
@@ -2297,9 +2131,9 @@
 
 			List<PropertyDefinition> oldProperties = oldDataTypeDefinition.getProperties();
 
-			String newDerivedFromName = getDerivedFromName(newDataTypeDefinition);
+			String newDerivedFromName = newDataTypeDefinition.getDerivedFromName();
 
-			String oldDerivedFromName = getDerivedFromName(oldDataTypeDefinition);
+			String oldDerivedFromName = oldDataTypeDefinition.getDerivedFromName();
 
 			String dataTypeName = newDataTypeDefinition.getName();
 
@@ -2317,12 +2151,24 @@
 				result = Either.right(StorageOperationStatus.OK);
 				return result;
 			}
+            Map<String, String> newDescriptions = getPropertyDescriptionsToUpdate(oldProperties, newProperties);
+
+            if(MapUtils.isNotEmpty(newDescriptions)){
+
+                TitanOperationStatus updatePropertiesStatus = updateDataTypePropertyDescriptions(oldDataTypeDefinition.getUniqueId(), newDescriptions);
+                if (updatePropertiesStatus != TitanOperationStatus.OK) {
+                    log.debug("#updateDataType - Failed to update the descriptions of the properties of the data type {}. Status is {}", oldDataTypeDefinition, updatePropertiesStatus);
+                    BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError(UPDATE_DATA_TYPE, PROPERTY);
+                    result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updatePropertiesStatus));
+                    return result;
+                }
+            }
 
 			Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(oldDataTypeDefinition.getUniqueId(), propertiesToAdd);
 
 			if (addPropertiesToDataType.isRight()) {
 				log.debug("Failed to update data type {} to Graph. Status is {}", oldDataTypeDefinition, addPropertiesToDataType.right().value().name());
-				BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("UpdateDataType", "Property");
+				BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError(UPDATE_DATA_TYPE, PROPERTY);
 				result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesToDataType.right().value()));
 				return result;
 			} else {
@@ -2331,7 +2177,7 @@
 				if (dataTypeByUid.isRight()) {
 					TitanOperationStatus status = addPropertiesToDataType.right().value();
 					log.debug("Failed to get data type {} after update. Status is {}", oldDataTypeDefinition.getUniqueId(), status.name());
-					BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("UpdateDataType", "Property", status.name());
+					BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError(UPDATE_DATA_TYPE, PROPERTY, status.name());
 					result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
 				} else {
 					result = Either.left(dataTypeByUid.left().value());
@@ -2341,12 +2187,12 @@
 			return result;
 
 		} finally {
-			if (false == inTransaction) {
+			if (!inTransaction) {
 				if (result == null || result.isRight()) {
-					log.error("Going to execute rollback on graph.");
+					log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
 					titanGenericDao.rollback();
 				} else {
-					log.debug("Going to execute commit on graph.");
+					log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
 					titanGenericDao.commit();
 				}
 			}
@@ -2354,17 +2200,12 @@
 
 	}
 
-	private String getDerivedFromName(DataTypeDefinition dataTypeDefinition) {
-		String derivedFromName = dataTypeDefinition.getDerivedFromName();
-		return derivedFromName;
-	}
-
 	private boolean isPropertyTypeChanged(String dataTypeName, List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, List<PropertyDefinition> outputPropertiesToAdd) {
 
 		if (newProperties != null && oldProperties != null) {
 
-			Map<String, PropertyDefinition> newPropsMapper = newProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
-			Map<String, PropertyDefinition> oldPropsMapper = oldProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
+			Map<String, PropertyDefinition> newPropsMapper = newProperties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, p -> p));
+			Map<String, PropertyDefinition> oldPropsMapper = oldProperties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, p -> p));
 
 			for (Entry<String, PropertyDefinition> newPropertyEntry : newPropsMapper.entrySet()) {
 
@@ -2384,12 +2225,12 @@
 				String newType = propDef.getType();
 				String newEntryType = getEntryType(propDef);
 
-				if (false == oldType.equals(newType)) {
+				if (!oldType.equals(newType)) {
 					log.debug("Existing property {} in data type {} has a differnet type {} than the new one {}", propName, dataTypeName, oldType, newType);
 					return true;
 				}
 
-				if (false == equalsEntryTypes(oldEntryType, newEntryType)) {
+				if (!equalsEntryTypes(oldEntryType, newEntryType)) {
 					log.debug("Existing property {} in data type {} has a differnet entry type {} than the new one {}", propName, dataTypeName, oldEntryType, newEntryType);
 					return true;
 				}
@@ -2427,19 +2268,19 @@
 	private boolean isPropertyOmitted(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) {
 
 		boolean isValid = validateChangeInCaseOfEmptyProperties(newProperties, oldProperties, dataTypeName);
-		if (false == isValid) {
+		if (!isValid) {
 			log.debug("At least one property is missing in the new data type {}", dataTypeName);
 			return false;
 		}
 
 		if (newProperties != null && oldProperties != null) {
 
-			List<String> newProps = newProperties.stream().map(p -> p.getName()).collect(Collectors.toList());
-			List<String> oldProps = oldProperties.stream().map(p -> p.getName()).collect(Collectors.toList());
+			List<String> newProps = newProperties.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList());
+			List<String> oldProps = oldProperties.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList());
 
-			if (false == newProps.containsAll(oldProps)) {
+			if (!newProps.containsAll(oldProps)) {
 				StringJoiner joiner = new StringJoiner(",", "[", "]");
-				newProps.forEach(p -> joiner.add(p));
+				newProps.forEach(joiner::add);
 				log.debug("Properties {} in data type {} are missing, but they already defined in the existing data type", joiner.toString(), dataTypeName);
 				return true;
 			}
@@ -2473,7 +2314,7 @@
 
 		if (newDerivedFromName != null) {
 			boolean isEqual = newDerivedFromName.equals(oldDerivedFromName);
-			if (false == isEqual) {
+			if (!isEqual) {
 				log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName);
 			}
 			return !isEqual;
@@ -2487,43 +2328,170 @@
 	}
 
 	/**
-	 * 
-	 * Future - unfinished
-	 * 
-	 * @param type
-	 * @param value
+	 * @param instanceId
+	 * @param nodeType
 	 * @return
 	 */
-	public boolean isValueToscaFunction(String type, String value) {
-
-		boolean result = false;
-
-		if (ToscaPropertyType.STRING.getType().equals(type) || isScalarDerivedFromString(type)) {
-
-		}
-
-		String[] functions = { "get_input" };
-
-		if (value != null) {
-
-			for (String function : functions) {
-
-			}
-
-		}
-
-		return result;
-
+	public Either<Integer, StorageOperationStatus> increaseAndGetObjInstancePropertyCounter(String instanceId, NodeTypeEnum nodeType) {
+	    Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph();
+	    if (graphResult.isRight()) {
+	        return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value()));
+	    }
+	    Either<TitanVertex, TitanOperationStatus> vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), instanceId);
+	    if (vertexService.isRight()) {
+	        log.debug("failed to fetch vertex of resource instance for id = {}", instanceId);
+	        return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value()));
+	    }
+	    Vertex vertex = vertexService.left().value();
+	    
+	    VertexProperty<Object> vertexProperty = vertex.property(GraphPropertiesDictionary.PROPERTY_COUNTER.getProperty());
+	    Integer counter = 0;
+	    if (vertexProperty.isPresent() && vertexProperty.value() != null) {
+	        counter = (Integer) vertexProperty.value();
+	    }
+	    
+	    counter++;
+	    vertex.property(GraphPropertiesDictionary.PROPERTY_COUNTER.getProperty(), counter);
+	    
+	    return Either.left(counter);
 	}
 
-	/**
-	 * Future - unfinished
-	 * 
-	 * @param type
-	 * @return
-	 */
-	private boolean isScalarDerivedFromString(String type) {
-		// TODO Auto-generated method stub
-		return false;
-	}
+
+	public Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertiesUniqueness(Map<String, PropertyDefinition> inheritedProperties, List<PropertyDefinition> properties) {
+        Either<List<PropertyDefinition>, TitanOperationStatus> result = Either.left(properties);
+
+        for (PropertyDefinition property : properties) {
+            TitanOperationStatus status = validatePropertyUniqueness(inheritedProperties, property);
+            if (status != TitanOperationStatus.OK) {
+                result = Either.right(status);
+                break;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Validates uniqueness of examined property by comparing it with properties in propertiesOfType
+     * and updates if need type and inner type of the property.
+     */
+    private TitanOperationStatus validatePropertyUniqueness(Map<String, PropertyDefinition> inheritedProperties, PropertyDefinition property) {
+        String propertyName = property.getName();
+        String propertyType = property.getType();
+
+        TitanOperationStatus result = TitanOperationStatus.OK;
+        if (inheritedProperties.containsKey(propertyName)) {
+            PropertyDefinition defaultProperty = inheritedProperties.get(propertyName);
+            if (typesMismatch(propertyType, defaultProperty.getType())) {
+                log.error("#validatePropertyUniqueness - Property with name {} and different type already exists.", propertyName);
+                result = TitanOperationStatus.PROPERTY_NAME_ALREADY_EXISTS;
+            } else {
+                property.setType(defaultProperty.getType());
+                String innerType = defaultProperty.getSchemaType();
+
+                PropertyDataDefinition schemaProperty = property.getSchemaProperty();
+                if (schemaProperty != null) {
+                    schemaProperty.setType(innerType);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    private boolean typesMismatch(String type1, String type2) {
+        return type1 != null && type2 != null && !type2.equals(type1);
+    }
+
+
+    public <T extends GraphNode> Either<Map<String, PropertyDefinition>, TitanOperationStatus> getAllTypePropertiesFromAllDerivedFrom(String nextParentUid,
+                                                                                                                                     NodeTypeEnum nodeType,
+                                                                                                                                     Class<T> clazz) {
+        Map<String, PropertyDefinition> allProperies = new HashMap<>();
+        return getTypePropertiesFromDerivedFromRecursively(nextParentUid, allProperies, nodeType, clazz);
+    }
+
+    private <T extends GraphNode> Either<Map<String, PropertyDefinition>, TitanOperationStatus> getTypePropertiesFromDerivedFromRecursively(String nextParentUid, 
+                                                                                                                        Map<String, PropertyDefinition> allProperies,
+                                                                                                                        NodeTypeEnum nodeType,
+                                                                                                                        Class<T> clazz) {
+        TitanOperationStatus error;
+        Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType),
+                                                                                                nextParentUid, GraphEdgeLabels.DERIVED_FROM, nodeType, clazz);
+        if (childrenNodes.isRight()) {
+            if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) {
+                error = childrenNodes.right().value();
+                log.debug("#getTypePropertiesFromDerivedFromRecursively - Couldn't fetch derived from node with UID {}, error: {}", nextParentUid, error);
+                return Either.right(error);
+            }
+            else {
+                log.debug("#getTypePropertiesFromDerivedFromRecursively - Derived from node is not found with UID {} - this is OK for root.", nextParentUid);
+                return Either.left(allProperies);
+            }
+        } else {
+
+            Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesOfTypeRes = findPropertiesOfNode(nodeType, nextParentUid);
+            if (allPropertiesOfTypeRes.isRight() && !allPropertiesOfTypeRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
+                error = allPropertiesOfTypeRes.right().value();
+                log.error("#getTypePropertiesFromDerivedFromRecursively - Failed to retrieve properties for node with UID {} from graph. status is {}", nextParentUid, error);
+                return Either.right(error);
+            } else if (allPropertiesOfTypeRes.isLeft()) {
+                if (allProperies.isEmpty()) {
+                    allProperies.putAll(allPropertiesOfTypeRes.left().value());
+                } else {
+                    allProperies.putAll(allPropertiesOfTypeRes.left().value().entrySet().stream().filter(e -> !allProperies.containsKey(e.getKey())).collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
+                }
+            }
+            return getTypePropertiesFromDerivedFromRecursively(childrenNodes.left().value().get(0).getLeft().getUniqueId(), allProperies, nodeType, clazz);
+        }
+    }
+    private TitanOperationStatus updateDataTypePropertyDescriptions(String uniqueId, Map<String, String> newDescriptions) {
+
+        if (MapUtils.isNotEmpty(newDescriptions)) {
+            Either<List<ImmutablePair<TitanVertex, Edge>>, TitanOperationStatus> getDataTypePropertiesRes = titanGenericDao.getChildrenVertecies(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.PROPERTY);
+
+            if(getDataTypePropertiesRes.isRight()){
+                log.debug("#updateDataTypePropertiesDescriptions - Failed to fetch the property verticies of the Data type {} ", uniqueId);
+                return getDataTypePropertiesRes.right().value();
+            }
+            getDataTypePropertiesRes.left().value().stream()
+                    .filter(pair -> newDescriptions.containsKey(getPropertyNameFromEdge(pair)))
+                    .forEach(pair -> setNewDescriptionToVertex(newDescriptions.get(getPropertyNameFromEdge(pair)), pair));
+
+        }
+        return TitanOperationStatus.OK;
+    }
+
+    private TitanVertexProperty<String> setNewDescriptionToVertex(String newDescription, ImmutablePair<TitanVertex, Edge> pair) {
+        return pair.getLeft().property(GraphPropertiesDictionary.DESCRIPTION.getProperty(), newDescription);
+    }
+
+    private String getPropertyNameFromEdge(ImmutablePair<TitanVertex, Edge> pair) {
+        return (String) pair.getRight().property(GraphPropertiesDictionary.NAME.getProperty()).value();
+    }
+
+    private Map<String, String> getPropertyDescriptionsToUpdate(List<PropertyDefinition> oldProperties, List<PropertyDefinition> newProperties) {
+
+        Map<String, PropertyDefinition> newPropertiesMap = newProperties
+                .stream()
+                .collect(Collectors.toMap(PropertyDefinition::getName, p->p));
+
+        return oldProperties
+                .stream()
+                .filter(p-> newPropertiesMap.containsKey(p.getName()) && !descriptionsEqual(p, newPropertiesMap.get(p.getName())))
+                .collect(Collectors.toMap(PropertyDefinition::getName, p->newPropertiesMap.get(p.getName()).getDescription()));
+    }
+
+    private boolean descriptionsEqual(PropertyDefinition property, PropertyDefinition otherProperty){
+        if(StringUtils.isEmpty(property.getDescription()) && StringUtils.isEmpty(otherProperty.getDescription())){
+            return true;
+        }
+        if(StringUtils.isNotEmpty(property.getDescription()) && StringUtils.isEmpty(otherProperty.getDescription())){
+            return false;
+        }
+        if(StringUtils.isEmpty(property.getDescription()) && StringUtils.isNotEmpty(otherProperty.getDescription())){
+            return false;
+        }
+        return property.getDescription().equals(otherProperty.getDescription());
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java
index 4cdb21a..058e9de 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java
@@ -20,10 +20,6 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
@@ -34,230 +30,182 @@
 import org.openecomp.sdc.common.api.Constants;
 import org.openecomp.sdc.common.util.ValidationUtils;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
 public class UniqueIdBuilder {
 
-	private static String DOT = ".";
-	private static final String HEAT_PARAM_PREFIX = "heat_";
-	
-	public static String buildPropertyUniqueId(String resourceId, String propertyName) {
-		return resourceId + DOT + propertyName;
-	}
-	
-	public static String buildHeatParameterUniqueId(String resourceId, String propertyName) {
-		return resourceId + DOT + HEAT_PARAM_PREFIX + propertyName;
-	}
+    private static String DOT = ".";
+    private static final String HEAT_PARAM_PREFIX = "heat_";
 
-	public static String buildHeatParameterValueUniqueId(String resourceId, String artifactLabel, String propertyName) {
-		return resourceId + DOT + artifactLabel + DOT + propertyName;
-	}
+    public static String buildPropertyUniqueId(String resourceId, String propertyName) {
+        return resourceId + DOT + propertyName;
+    }
 
-	private static UserData userData = new UserData();
-	private static TagData tagData = new TagData();
-	private static ResourceCategoryData resCategoryData = new ResourceCategoryData();
-	private static ServiceCategoryData serCategoryData = new ServiceCategoryData();
+    static String buildHeatParameterUniqueId(String resourceId, String propertyName) {
+        return resourceId + DOT + HEAT_PARAM_PREFIX + propertyName;
+    }
 
-	private static Map<NodeTypeEnum, String> nodeTypeToUniqueKeyMapper = new HashMap<NodeTypeEnum, String>();
+    static String buildHeatParameterValueUniqueId(String resourceId, String artifactLabel, String propertyName) {
+        return buildTypeUid(resourceId, artifactLabel, propertyName);
+    }
 
-	static {
+    private static UserData userData = new UserData();
+    private static TagData tagData = new TagData();
+    private static ResourceCategoryData resCategoryData = new ResourceCategoryData();
+    private static ServiceCategoryData serCategoryData = new ServiceCategoryData();
 
-		nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.User, userData.getUniqueIdKey());
-		nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.Tag, tagData.getUniqueIdKey());
-		nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.ResourceCategory, resCategoryData.getUniqueIdKey());
-		nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.ServiceCategory, serCategoryData.getUniqueIdKey());
-	}
+    private static Map<NodeTypeEnum, String> nodeTypeToUniqueKeyMapper = new HashMap<>();
 
-	/**
-	 * find the unique id key of a node on the graph
-	 * 
-	 * @param nodeTypeEnum
-	 * @return
-	 */
-	public static String getKeyByNodeType(NodeTypeEnum nodeTypeEnum) {
+    static {
 
-		String key = nodeTypeToUniqueKeyMapper.get(nodeTypeEnum);
-		if (key == null) {
-			key = GraphPropertiesDictionary.UNIQUE_ID.getProperty();
-		}
+        nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.User, userData.getUniqueIdKey());
+        nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.Tag, tagData.getUniqueIdKey());
+        nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.ResourceCategory, resCategoryData.getUniqueIdKey());
+        nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.ServiceCategory, serCategoryData.getUniqueIdKey());
+    }
 
-		return key;
-	}
+    /**
+     * find the unique id key of a node on the graph
+     *
+     * @param nodeTypeEnum
+     * @return
+     */
+    public static String getKeyByNodeType(NodeTypeEnum nodeTypeEnum) {
 
-	public static String buildResourceUniqueId() {
-		return generateUUID();
-	}
+        String key = nodeTypeToUniqueKeyMapper.get(nodeTypeEnum);
+        if (key == null) {
+            key = GraphPropertiesDictionary.UNIQUE_ID.getProperty();
+        }
 
-	public static String generateUUID() {
-		UUID uuid = UUID.randomUUID();
-		return uuid.toString();
-	}
+        return key;
+    }
 
-	public static String buildComponentUniqueId() {
-		return generateUUID();
-	}
+    public static String buildResourceUniqueId() {
+        return generateUUID();
+    }
 
-	public static String buildConstantProductId() {
-		return generateUUID();
-	}
+    public static String generateUUID() {
+        UUID uuid = UUID.randomUUID();
+        return uuid.toString();
+    }
 
-	public static String buildCapabilityTypeUid(String type) {
-		return type;
-	}
+    public static String buildComponentUniqueId() {
+        return generateUUID();
+    }
 
-	public static String buildAttributeUid(String resourceId, String attName) {
-		return NodeTypeEnum.Attribute.getName() + DOT + resourceId + DOT + attName;
-	}
-	public static String buildArtifactUid(String parentId, String label) {
-		return parentId + DOT + label;
-	}
-	public static String buildRequirementUid(String resourceId, String reqName) {
-		return resourceId + DOT + reqName;
-	}
+    static String buildCapabilityTypeUid(String type) {
+        return type;
+    }
 
-	public static String buildRequirementImplUid(String resourceId, String reqName) {
+    public static String buildAttributeUid(String resourceId, String attName) {
+        return buildTypeUid(NodeTypeEnum.Attribute.getName(), resourceId, attName);
+    }
+    public static String buildRequirementUid(String resourceId, String reqName) {
+        return resourceId + DOT + reqName;
+    }
 
-		return NodeTypeEnum.RequirementImpl.getName() + DOT + resourceId + DOT + reqName;
+    public static String buildCapabilityUid(String resourceId, String capabilityName) {
+        return buildTypeUid(NodeTypeEnum.Capability.getName(), resourceId, capabilityName);
+    }
 
-	}
+    public static String buildArtifactByInterfaceUniqueId(String resourceId, String interfaceName, String operation, String artifactLabel) {
 
-	public static String buildCapabilityUid(String resourceId, String capabilityName) {
-		return NodeTypeEnum.Capability.getName() + DOT + resourceId + DOT + capabilityName;
-	}
+        return resourceId + DOT + interfaceName + DOT + operation + DOT + artifactLabel;
+    }
 
-	public static String buildCapabilityInstanceUid(String parentId, String capabilityName) {
-		return NodeTypeEnum.CapabilityInst.getName() + DOT + parentId + DOT + capabilityName;
-	}
+    public static String buildInstanceArtifactUniqueId(String parentId, String instanceId, String artifactLabel) {
 
-	public static String buildPropertyValueUniqueId(String parentId, String paramName) {
-		return NodeTypeEnum.PropertyValue.getName() + DOT + parentId + DOT + paramName;
-	}
-	
-	public static String buildArtifactByInterfaceUniqueId(String resourceId, String interfaceName, String operation, String artifactLabel) {
+        return buildTypeUid(parentId, instanceId, artifactLabel);
+    }
 
-		return resourceId + DOT + interfaceName + DOT + operation + DOT + artifactLabel;
-	}
-	
-	public static String buildInstanceArtifactUniqueId(String parentId, String instanceId, String artifactLabel) {
+    public static String buildResourceInstanceUniuqeId(String serviceId, String resourceId, String logicalName) {
 
-		return parentId + DOT + instanceId + DOT + artifactLabel;
-	}
+        return buildTypeUid(serviceId, resourceId, logicalName);
+    }
 
-	// public static String
-	// buildArtifactByInterfaceUniqueIdAndRsrcNameVersion(String
-	// resourceName,String resourceVersion,String interfaceName,String
-	// operation,String artifactLabel) {
-	// String resourceId = UniqueIdBuilder.buildResourceUniqueId(resourceName,
-	// resourceVersion);
-	// return resourceId + DOT + interfaceName + DOT +operation + DOT +
-	// artifactLabel;
-	// }
-	public static String buildArtifactByInterfaceUniqueIdAndRsrcId(String resourceId, String interfaceName, String operation, String artifactLabel) {
-		return resourceId + DOT + interfaceName + DOT + operation + DOT + artifactLabel;
-	}
+    public static String buildRelationsipInstInstanceUid(String resourceInstUid, String requirement) {
 
-	public static String buildOperationByInterfaceUniqueId(String resourceId, String interfaceName, String operation) {
+        return generateUUID();
+    }
 
-		return resourceId + DOT + interfaceName + DOT + operation;
-	}
+    /*
+     * TODO Pavel To be removed when new category logic comes in
+     */
+    static String buildResourceCategoryUid(String categoryName, String subcategoryName, NodeTypeEnum type) {
+        return buildTypeUid(type.getName(), categoryName, subcategoryName);
+    }
 
-	public static String buildInterfaceUniqueId(String resourceId, String interfaceName) {
-		return resourceId + DOT + interfaceName;
-	}
+    /*
+     * TODO Pavel To be removed when new category logic comes in
+     */
+    static String buildServiceCategoryUid(String categoryName, NodeTypeEnum type) {
+        return type.getName() + DOT + categoryName;
+    }
 
-	public static String buildResourceInstanceUniuqeId(String serviceId, String resourceId, String logicalName) {
+    // New logic
+    public static String buildCategoryUid(String categoryName, NodeTypeEnum type) {
+        return type.getName() + DOT + categoryName;
+    }
+    public static String buildComponentCategoryUid(String categoryName, VertexTypeEnum type) {
+        return type.getName() + DOT + ValidationUtils.normalizeCategoryName4Uniqueness(categoryName);
+    }
 
-		return serviceId + DOT + resourceId + DOT + logicalName;
-	}
+    public static String buildSubCategoryUid(String categoryUid, String subCategoryName) {
+        return categoryUid + DOT + subCategoryName;
+    }
 
-	public static String buildRelationsipInstInstanceUid(String resourceInstUid, String requirement) {
+    public static String buildGroupingUid(String subCategoryUid, String groupingName) {
+        return subCategoryUid + DOT + groupingName;
+    }
 
-		return generateUUID();
-	}
+    static String buildResourceInstancePropertyValueUid(String resourceInstanceUniqueId, Integer index) {
+        return resourceInstanceUniqueId + DOT + "property" + DOT + index;
+    }
 
-	/*
-	 * TODO Pavel To be removed when new category logic comes in
-	 */
-	public static String buildResourceCategoryUid(String categoryName, String subcategoryName, NodeTypeEnum type) {
-		return type.getName() + DOT + categoryName + DOT + subcategoryName;
-	}
+    public static String buildComponentPropertyUniqueId(String resourceId, String propertyName) {
+        return buildTypeUid(NodeTypeEnum.Property.getName(), resourceId, propertyName);
+    }
 
-	/*
-	 * TODO Pavel To be removed when new category logic comes in
-	 */
-	public static String buildServiceCategoryUid(String categoryName, NodeTypeEnum type) {
-		return type.getName() + DOT + categoryName;
-	}
+    static String buildResourceInstanceAttributeValueUid(String resourceInstanceUniqueId, Integer index) {
+        return resourceInstanceUniqueId + DOT + "attribute" + DOT + index;
+    }
 
-	// New logic
-	public static String buildCategoryUid(String categoryName, NodeTypeEnum type) {
-		return type.getName() + DOT + categoryName;
-	}
-	public static String buildComponentCategoryUid(String categoryName, VertexTypeEnum type) {
-		return type.getName() + DOT + ValidationUtils.normalizeCategoryName4Uniqueness(categoryName);
-	}
+    static String buildResourceInstanceInputValueUid(String resourceInstanceUniqueId, Integer index) {
+        return resourceInstanceUniqueId + DOT + "input" + DOT + index;
+    }
 
-	public static String buildSubCategoryUid(String categoryUid, String subCategoryName) {
-		return categoryUid + DOT + subCategoryName;
-	}
+    static String buildAdditionalInformationUniqueId(String resourceUniqueId) {
+        return resourceUniqueId + DOT + "additionalinformation";
+    }
 
-	public static String buildGroupingUid(String subCategoryUid, String groupingName) {
-		return subCategoryUid + DOT + groupingName;
-	}
+    static String buildDataTypeUid(String name) {
+        return name + DOT + "datatype";
+    }
 
-	public static String buildResourceInstancePropertyValueUid(String resourceInstanceUniqueId, Integer index) {
-		return resourceInstanceUniqueId + DOT + "property" + DOT + index;
-	}
-	
-	public static String buildComponentPropertyUniqueId(String resourceId, String propertyName) {
-		return NodeTypeEnum.Property.getName() + DOT + resourceId + DOT + propertyName;
-	}
+    public static String buildInvariantUUID() {
+        return generateUUID();
+    }
 
-	public static String buildResourceInstanceAttributeValueUid(String resourceInstanceUniqueId, Integer index) {
-		return resourceInstanceUniqueId + DOT + "attribute" + DOT + index;
-	}
+    static String buildGroupTypeUid(String type, String version, String resourceName) {
+        return buildTypeUid(type, version, resourceName);
+    }
 
-	public static String buildResourceInstanceInputValueUid(String resourceInstanceUniqueId, Integer index) {
-		return resourceInstanceUniqueId + DOT + "input" + DOT + index;
-	}
+    static String buildPolicyTypeUid(String type, String version, String resourceName) {
+        return buildTypeUid(type, version, resourceName);
+    }
 
-	public static String buildAdditionalInformationUniqueId(String resourceUniqueId) {
-		return resourceUniqueId + DOT + "additionalinformation";
-	}
+    static String buildTypeUid(String type, String version, String resourceName) {
+        return type + DOT + version + DOT + resourceName;
+    }
 
-	public static String buildHeatParamValueUid(String heatEnvArtifactId, String parameterName) {
-		return heatEnvArtifactId + DOT + parameterName;
-	}
+    public static String buildPolicyUniqueId(String componentId, String name) {
+        return componentId + DOT + name + Constants.POLICY_UID_POSTFIX;
+    }
 
-	public static String buildDataTypeUid(String name) {
-		return name + DOT + "datatype";
-	}
+    public static String buildGroupPropertyValueUid(String groupUniqueId, Integer index) {
+        return groupUniqueId + DOT + "property" + DOT + index;
 
-	public static String buildInvariantUUID() {
-		return generateUUID();
-	}
-
-	public static String buildGroupTypeUid(String type, String version) {
-		return type + DOT + version + DOT + "grouptype";
-	}
-
-	public static String buildPolicyTypeUid(String type, String version) {
-		return type + DOT + version + DOT + "policytype";
-	}
-
-	public static String buildGroupUniqueId(String componentId, String name) {
-		return componentId + DOT + name + DOT + "group";
-	}
-	
-	public static String buildPolicyUniqueId(String componentId, String name) {
-		return componentId + DOT + name + Constants.POLICY_UID_POSTFIX;
-	}
-
-	public static String buildGroupPropertyValueUid(String groupUniqueId, Integer index) {
-		return groupUniqueId + DOT + "property" + DOT + index;
-
-	}
-	
-	public static String buildUserFunctionalMenuUid(String userId) {
-		return userId + DOT + "functionalmenu";
-
-	}
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java
index 9aa2314..72c370f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java
@@ -20,12 +20,9 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
+import org.apache.commons.lang3.BooleanUtils;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -43,372 +40,362 @@
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.resources.data.UserData;
 import org.openecomp.sdc.common.datastructure.Wrapper;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.MethodActivationStatusEnum;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
 
-import com.thinkaurelius.titan.core.TitanVertex;
+import java.util.*;
 
-import fj.data.Either;
+import static org.apache.commons.collections.CollectionUtils.isEmpty;
 
 @Component("user-operation")
 public class UserAdminOperation implements IUserAdminOperation {
 
-	private TitanGenericDao titanGenericDao;
+    private TitanGenericDao titanGenericDao;
 
-	public UserAdminOperation(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao) {
-		super();
-		this.titanGenericDao = titanGenericDao;
+    public UserAdminOperation(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao) {
+        super();
+        this.titanGenericDao = titanGenericDao;
 
-	}
+    }
 
-	private static Logger log = LoggerFactory.getLogger(UserAdminOperation.class.getName());
+    private static final Logger log = Logger.getLogger(UserAdminOperation.class.getName());
 
-	@Override
-	public Either<User, ActionStatus> getUserData(String id, boolean inTransaction) {
-		return getUserData(id, true, inTransaction);
-	}
+    @Override
+    public Either<User, ActionStatus> getUserData(String id, boolean inTransaction) {
+        return getUserData(id, true, inTransaction);
+    }
 
-	private Either<User, ActionStatus> getUserData(String id, boolean isActive, boolean inTransaction) {
-		log.debug("getUserData - start");
-		Wrapper<Either<User, ActionStatus>> resultWrapper = new Wrapper<>();
-		Wrapper<UserData> userWrapper = new Wrapper<>();
-		try {
-			validateUserExists(resultWrapper, userWrapper, id);
+    private Either<User, ActionStatus> getUserData(String id, boolean isActive, boolean inTransaction) {
+        log.debug("getUserData - start");
+        Wrapper<Either<User, ActionStatus>> resultWrapper = new Wrapper<>();
+        Wrapper<UserData> userWrapper = new Wrapper<>();
+        try {
+            validateUserExists(resultWrapper, userWrapper, id);
 
-			if (resultWrapper.isEmpty()) {
-				validateUserData(resultWrapper, userWrapper.getInnerElement(), id);
+            if (resultWrapper.isEmpty()) {
+                validateUserData(resultWrapper, userWrapper.getInnerElement(), id);
 
-			}
-			if (resultWrapper.isEmpty()) {
-				if (isActive) {
-					validateActiveUser(resultWrapper, userWrapper.getInnerElement());
-				} else {
-					validateInActiveUser(resultWrapper, userWrapper.getInnerElement());
-				}
-			}
+            }
+            if (resultWrapper.isEmpty()) {
+                if (isActive) {
+                    validateActiveUser(resultWrapper, userWrapper.getInnerElement());
+                } else {
+                    validateInActiveUser(resultWrapper, userWrapper.getInnerElement());
+                }
+            }
 
-			if (resultWrapper.isEmpty()) {
-				Either<User, ActionStatus> result = Either.left(convertToUser(userWrapper.getInnerElement()));
-				resultWrapper.setInnerElement(result);
-			}
+            if (resultWrapper.isEmpty()) {
+                resultWrapper.setInnerElement(Either.left(convertToUser(userWrapper.getInnerElement())));
+            }
 
-			return resultWrapper.getInnerElement();
-		} finally {
-			if (!inTransaction) {
-				titanGenericDao.commit();
-			}
-			log.debug("getUserData - end");
-		}
-	}
+            return resultWrapper.getInnerElement();
+        } finally {
+            if (!inTransaction) {
+                titanGenericDao.commit();
+            }
+            log.debug("getUserData - end");
+        }
+    }
 
-	private void validateInActiveUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
-		User user = convertToUser(userData);
-		if (user.getStatus() == UserStatusEnum.ACTIVE) {
-			Either<User, ActionStatus> result = Either.right(ActionStatus.USER_NOT_FOUND);
-			resultWrapper.setInnerElement(result);
-		}
-	}
+    private void validateInActiveUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
+        User user = convertToUser(userData);
+        if (user.getStatus() == UserStatusEnum.ACTIVE) {
+            resultWrapper.setInnerElement(Either.right(ActionStatus.USER_NOT_FOUND));
+        }
+    }
 
-	private void validateActiveUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
-		User user = convertToUser(userData);
-		if (user.getStatus() == UserStatusEnum.INACTIVE) {
-			Either<User, ActionStatus> result = Either.right(ActionStatus.USER_INACTIVE);
-			resultWrapper.setInnerElement(result);
-		}
-	}
+    private void validateActiveUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
+        User user = convertToUser(userData);
+        if (user.getStatus() == UserStatusEnum.INACTIVE) {
+            resultWrapper.setInnerElement(Either.right(ActionStatus.USER_INACTIVE));
+        }
+    }
 
-	private void validateUserData(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData, String id) {
-		if (userData == null) {
-			log.debug("Problem get User with userId {}. Reason -  either.left().value() = null", id);
-			Either<User, ActionStatus> result = Either.right(ActionStatus.GENERAL_ERROR);
-			resultWrapper.setInnerElement(result);
-		}
-	}
+    private void validateUserData(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData, String id) {
+        if (userData == null) {
+            log.debug("Problem get User with userId {}. Reason -  either.left().value() = null", id);
+            resultWrapper.setInnerElement(Either.right(ActionStatus.GENERAL_ERROR));
+        }
+    }
 
-	private void validateUserExists(Wrapper<Either<User, ActionStatus>> resultWrapper, Wrapper<UserData> userWrapper, String id) {
-		Either<User, ActionStatus> result;
-		if (id == null) {
-			log.info("User userId  is empty");
-			result = Either.right(ActionStatus.MISSING_INFORMATION);
-			resultWrapper.setInnerElement(result);
-			return;
-		}
-		id = id.toLowerCase();
-		Either<UserData, TitanOperationStatus> either = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class);
+    private void validateUserExists(Wrapper<Either<User, ActionStatus>> resultWrapper, Wrapper<UserData> userWrapper, String id) {
+        if (id == null) {
+            log.info("User userId  is empty");
+            resultWrapper.setInnerElement(Either.right(ActionStatus.MISSING_INFORMATION));
+            return;
+        }
+        id = id.toLowerCase();
+        Either<UserData, TitanOperationStatus> either = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class);
 
-		if (either.isRight()) {
-			resultWrapper.setInnerElement(getUserNotFoundError(id, either.right().value()));
-		} else {
-			userWrapper.setInnerElement(either.left().value());
-		}
-	}
+        if (either.isRight()) {
+            resultWrapper.setInnerElement(getUserNotFoundError(id, either.right().value()));
+        } else {
+            userWrapper.setInnerElement(either.left().value());
+        }
+    }
 
-	@Override
-	public Either<User, StorageOperationStatus> saveUserData(User user) {
+    @Override
+    public Either<User, StorageOperationStatus> saveUserData(User user) {
+        Either<UserData, TitanOperationStatus> result = null;
+        try {
+            UserData userData = convertToUserData(user);
+            result = titanGenericDao.createNode(userData, UserData.class);
+            if (result.isRight()) {
+                log.debug("Problem while saving User  {}. Reason - {}", userData.getUserId(), result.right().value());
+                return Either.right(StorageOperationStatus.GENERAL_ERROR);
+            }
+            log.debug("User {} saved successfully", userData.getUserId());
+            return Either.left(convertToUser(result.left().value()));
 
-		Either<UserData, TitanOperationStatus> result = null;
-		try {
-			UserData userData = convertToUserData(user);
-			result = titanGenericDao.createNode(userData, UserData.class);
-			if (result.isRight()) {
-				log.debug("Problem while saving User  {}. Reason - {}",userData.toString(),result.right().value().name());
-				return Either.right(StorageOperationStatus.GENERAL_ERROR);
-			}
-			log.debug("User {} saved successfully",userData.toString());
-			return Either.left(convertToUser(result.left().value()));
+        } finally {
 
-		} finally {
+            if (result == null || result.isRight()) {
+                log.error("saveUserData - Failed");
+                titanGenericDao.rollback();
+            } else {
+                log.debug("saveUserData - end");
+                titanGenericDao.commit();
+            }
+        }
+    }
 
-			if (result == null || result.isRight()) {
-				log.error("saveUserData - Failed");
-				titanGenericDao.rollback();
-			} else {
-				log.debug("saveUserData - end");
-				titanGenericDao.commit();
-			}
-		}
-	}
+    @Override
+    public Either<User, StorageOperationStatus> updateUserData(User user) {
+        Either<UserData, TitanOperationStatus> result = null;
+        try {
+            log.debug("updateUserData - start");
+            UserData userData = convertToUserData(user);
+            result = titanGenericDao.updateNode(userData, UserData.class);
+            if (result.isRight()) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Problem while updating User {}. Reason - {}", userData.toString(), result.right().value());
+                }
+                return Either.right(StorageOperationStatus.GENERAL_ERROR);
+            }
+            log.debug("User {} updated successfully",userData.getUserId());
+            return Either.left(convertToUser(result.left().value()));
 
-	@Override
-	public Either<User, StorageOperationStatus> updateUserData(User user) {
-		Either<UserData, TitanOperationStatus> result = null;
-		try {
-			log.debug("updateUserData - start");
-			UserData userData = convertToUserData(user);
-			result = titanGenericDao.updateNode(userData, UserData.class);
-			if (result.isRight()) {
-				log.debug("Problem while updating User {}. Reason - {}",userData.toString(),result.right().value().name());
-				return Either.right(StorageOperationStatus.GENERAL_ERROR);
-			}
-			log.debug("User {} updated successfully",userData.toString());
-			return Either.left(convertToUser(result.left().value()));
+        } finally {
 
-		} finally {
+            if (result == null || result.isRight()) {
+                log.error("updateUserData - Failed");
+                titanGenericDao.rollback();
+            } else {
+                log.debug("updateUserData - end");
+                titanGenericDao.commit();
+            }
 
-			if (result == null || result.isRight()) {
-				log.error("updateUserData - Failed");
-				titanGenericDao.rollback();
-			} else {
-				log.debug("updateUserData - end");
-				titanGenericDao.commit();
-			}
+        }
+    }
 
-		}
-	}
+    @Override
+    public Either<User, StorageOperationStatus> deActivateUser(User user) {
+        Either<User, StorageOperationStatus> result;
+        user.setStatus(UserStatusEnum.INACTIVE);
+        Either<User, StorageOperationStatus> status = updateUserData(user);
+        if (status.isRight()) {
+            result = Either.right(status.right().value());
+        } else {
+            result = Either.left(user);
+        }
+        return result;
+    }
 
-	@Override
-	public Either<User, StorageOperationStatus> deActivateUser(User user) {
-		Either<User, StorageOperationStatus> result;
-		user.setStatus(UserStatusEnum.INACTIVE);
-		Either<User, StorageOperationStatus> status = updateUserData(user);
-		if (status.isRight()) {
-			result = Either.right(status.right().value());
-		} else {
-			result = Either.left(user);
-		}
-		return result;
-	}
+    @Override
+    public Either<User, ActionStatus> deleteUserData(String id) {
+        Either<User, ActionStatus> result;
+        Either<UserData, TitanOperationStatus> eitherGet = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class);
+        if (eitherGet.isRight()) {
+            log.debug("Problem while retriving user with userId {}",id);
+            if (eitherGet.right().value() == TitanOperationStatus.NOT_FOUND) {
+                result = Either.right(ActionStatus.USER_NOT_FOUND);
+            } else {
+                result = Either.right(ActionStatus.GENERAL_ERROR);
+            }
+        } else {
+            result = deleteUserLogic(eitherGet.left().value());
+        }
+        return result;
+    }
 
-	@Override
-	public Either<User, ActionStatus> deleteUserData(String id) {
-		Either<User, ActionStatus> result;
-		Either<UserData, TitanOperationStatus> eitherGet = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class);
-		if (eitherGet.isRight()) {
-			log.debug("Problem while retriving user with userId {}",id);
-			if (eitherGet.right().value() == TitanOperationStatus.NOT_FOUND) {
-				result = Either.right(ActionStatus.USER_NOT_FOUND);
-			} else {
-				result = Either.right(ActionStatus.GENERAL_ERROR);
-			}
+    private Either<User, ActionStatus> deleteUserLogic(UserData userData) {
+        Wrapper<Either<User, ActionStatus>> resultWrapper = new Wrapper<>();
+        try {
+            validateUserHasNoConnections(resultWrapper, userData);
+            if (resultWrapper.isEmpty()) {
+                deleteUser(resultWrapper, userData);
+            }
+        } finally {
+            titanGenericDao.commit();
+        }
+        return resultWrapper.getInnerElement();
+    }
 
-		} else {
-			result = deleteUserLogic(eitherGet.left().value());
-		}
-		return result;
-	}
+    private void deleteUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
+        Either<UserData, TitanOperationStatus> eitherDelete = titanGenericDao.deleteNode(userData, UserData.class);
+        if (eitherDelete.isRight()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Problem while deleting User {}. Reason - {}", userData.toString(), eitherDelete.right().value());
+            }
+            resultWrapper.setInnerElement(Either.right(ActionStatus.GENERAL_ERROR));
+        } else {
+            log.debug("User {} deleted successfully",userData.getUserId());
+            resultWrapper.setInnerElement(Either.left(convertToUser(eitherDelete.left().value())));
+        }
+    }
 
-	private Either<User, ActionStatus> deleteUserLogic(UserData userData) {
-		Wrapper<Either<User, ActionStatus>> resultWrapper = new Wrapper<>();
-		try {
-			validateUserHasNoConnections(resultWrapper, userData);
+    private void validateUserHasNoConnections(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
+        if (resultWrapper.isEmpty()) {
 
-			if (resultWrapper.isEmpty()) {
-				deleteUser(resultWrapper, userData);
-			}
+            Either<List<Edge>, TitanOperationStatus> edgesForNode = titanGenericDao.getEdgesForNode(userData, Direction.BOTH);
+            if (edgesForNode.isRight()) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Problem while deleting User {}. Reason - {}", userData.getUserId(), edgesForNode.right().value());
+                }
+                resultWrapper.setInnerElement(Either.right(ActionStatus.GENERAL_ERROR));
+            } else {
+                List<Edge> vertexEdges = edgesForNode.left().value();
+                if (!isEmpty(vertexEdges)) {
+                    resultWrapper.setInnerElement(Either.right(ActionStatus.USER_HAS_ACTIVE_ELEMENTS));
+                }
+            }
+        }
+    }
 
-		} finally {
-			titanGenericDao.commit();
-		}
+    public Either<List<Edge>, StorageOperationStatus> getUserPendingTasksList(User user, Map<String, Object> properties) {
 
-		return resultWrapper.getInnerElement();
-	}
+        Either<TitanVertex, TitanOperationStatus> vertexUser = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), user.getUserId());
+        if (vertexUser.isRight()) {
+            TitanOperationStatus tos = vertexUser.right().value();
+            log.debug("Failed to get User {} from graph while retrieving pending tasks. Reason - {}", user.getUserId(), tos);
+            return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(tos));
+        }
+        List<Edge> pendingTasks = new ArrayList<>();
+        Either<List<Edge>, TitanOperationStatus> edges = titanGenericDao.getOutgoingEdgesByCriteria(vertexUser.left().value(), GraphEdgeLabels.STATE, properties);
+        if (edges.isRight() || edges.left().value() == null) {
+            TitanOperationStatus tos = edges.right().value();
+            if (tos == TitanOperationStatus.NOT_FOUND) {
+                return Either.left(pendingTasks);
+            } else {
+                log.debug("Failed while retrieving pending tasks for user {} . Reason - {}", user.getUserId(), tos);
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(tos));
+            }
+        }
+        for (Edge edge : edges.left().value()) {
+            if (!isComponentDeleted(edge.inVertex())) {
+                pendingTasks.add(edge);
+            }
+        }
+        logPendingTasks(user, pendingTasks);
+        return Either.left(pendingTasks);
+    }
 
-	private void deleteUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
-		Either<UserData, TitanOperationStatus> eitherDelete = titanGenericDao.deleteNode(userData, UserData.class);
-		if (eitherDelete.isRight()) {
-			log.debug("Problem while deleting User {}. Reason - {}",userData.toString(),eitherDelete.right().value().name());
-			Either<User, ActionStatus> result = Either.right(ActionStatus.GENERAL_ERROR);
-			resultWrapper.setInnerElement(result);
-		} else {
-			log.debug("User {} deleted successfully",userData.toString());
-			Either<User, ActionStatus> result = Either.left(convertToUser(eitherDelete.left().value()));
-			resultWrapper.setInnerElement(result);
-		}
-	}
+    private boolean isComponentDeleted(Vertex componentVertex) {
+        VertexProperty<Object> property = componentVertex.property(GraphPropertiesDictionary.IS_DELETED.getProperty());
+        if (property.isPresent()) {
+            return BooleanUtils.isTrue((Boolean) property.value());
+        }
+        return false;
+    }
 
-	private void validateUserHasNoConnections(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
-		if (resultWrapper.isEmpty()) {
+    private void logPendingTasks(User user, List<Edge> pendingTasks) {
+        if (log.isDebugEnabled()) {
+            for (Edge edge : pendingTasks) {
+                Object resourceUuid = edge.inVertex().property(GraphPropertyEnum.UNIQUE_ID.getProperty()).value();
+                Object componentName = edge.inVertex().property(GraphPropertyEnum.NAME.getProperty()).value();
+                Object componentState = edge.inVertex().property(GraphPropertyEnum.STATE.getProperty()).value();
+                log.debug("The user userId = {} is working on the component name = {} uid = {} in state {}", user.getUserId(), componentName, resourceUuid, componentState);
+            }
+        }
+    }
 
-			Either<List<Edge>, TitanOperationStatus> edgesForNode = titanGenericDao.getEdgesForNode(userData, Direction.BOTH);
-			if (edgesForNode.isRight()) {
-				log.debug("Problem while deleting User {}. Reason - {}",userData.toString(),edgesForNode.right().value().name());
-				Either<User, ActionStatus> result = Either.right(ActionStatus.GENERAL_ERROR);
-				resultWrapper.setInnerElement(result);
-			} else {
-				List<Edge> vertexEdges = edgesForNode.left().value();
-				if (vertexEdges.size() > 0) {
-					Either<User, ActionStatus> result = Either.right(ActionStatus.USER_HAS_ACTIVE_ELEMENTS);
-					resultWrapper.setInnerElement(result);
-				}
-			}
-		}
-	}
+    @Override
+    public Either<List<User>, ActionStatus> getAllUsersWithRole(String role, String status) {
+        try {
+            Map<String, Object> propertiesToMatch = new HashMap<>();
+            if (role != null && !role.trim().isEmpty()) {
+                propertiesToMatch.put(GraphPropertiesDictionary.ROLE.getProperty(), role);
+            }
+            if (status != null && !status.isEmpty()) {
+                propertiesToMatch.put(GraphPropertiesDictionary.USER_STATUS.getProperty(), status);
+            }
 
-	public Either<List<Edge>, StorageOperationStatus> getUserPendingTasksList(User user, Map<String, Object> properties) {
+            Either<List<UserData>, TitanOperationStatus> userNodes = titanGenericDao.getByCriteria(NodeTypeEnum.User, propertiesToMatch, UserData.class);
 
-		UserData userData = convertToUserData(user);
+            titanGenericDao.commit();
+            return convertToUsers(role, userNodes);
+        } finally {
+            titanGenericDao.commit();
+        }
+    }
 
-		Either<TitanVertex, TitanOperationStatus> vertexUser = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), user.getUserId());
-		if (vertexUser.isRight()) {
-			log.debug("Problem while deleting User {}. Reason - {}",userData.toString(),vertexUser.right().value().name());
-			return Either.right(StorageOperationStatus.GENERAL_ERROR);
-		}
+    private Either<List<User>, ActionStatus> convertToUsers(String role, Either<List<UserData>, TitanOperationStatus> userNodes) {
 
-		List<Edge> pandingTasks = new ArrayList<>();
-		Either<List<Edge>, TitanOperationStatus> edges = titanGenericDao.getOutgoingEdgesByCriteria(vertexUser.left().value(), GraphEdgeLabels.STATE, properties);
-
-		if (edges.isRight() || edges.left().value() == null) {
-			if (edges.right().value() == TitanOperationStatus.NOT_FOUND) {
-				return Either.left(pandingTasks);
-			} else {
-				log.debug("Problem while deleting User {}. Reason - ",userData.toString(),edges.right().value().name());
-				return Either.right(StorageOperationStatus.GENERAL_ERROR);
-			}
-		}
-
-		for (Edge edge : edges.left().value()) {
-			Vertex componentVertex = edge.inVertex();
-			VertexProperty<Object> property = componentVertex.property(GraphPropertiesDictionary.IS_DELETED.getProperty());
-			if (!property.isPresent()) {
-				pandingTasks.add(edge);
-			} else {
-				Boolean isDeletedValue = (java.lang.Boolean) property.value();
-				if (isDeletedValue == null || isDeletedValue == false) {
-					pandingTasks.add(edge);
-				}
-			}
-		}
-		
-		if(log.isDebugEnabled()) {
-			for (Edge edge : pandingTasks) {
-				Object resourceUuid = edge.inVertex().property(GraphPropertyEnum.UNIQUE_ID.getProperty()).value();
-				Object componentName = edge.inVertex().property(GraphPropertyEnum.NAME.getProperty()).value();
-				Object componentState = edge.inVertex().property(GraphPropertyEnum.STATE.getProperty()).value();
-				log.debug("The user userId = {} is working on the component name = {} uid = {} in state {}", user.getUserId(), componentName, resourceUuid, componentState);					
-			}
-		}
-		
-		return Either.left(pandingTasks);
-	}
-
-	@Override
-	public Either<List<User>, ActionStatus> getAllUsersWithRole(String role, String status) {
-		try {
-			List<User> result = new ArrayList<>();
-			Map<String, Object> propertiesToMatch = new HashMap<>();
-			if (role != null && !role.trim().isEmpty()) {
-				propertiesToMatch.put(GraphPropertiesDictionary.ROLE.getProperty(), role);
-			}
-			if (status != null && !status.isEmpty()) {
-				propertiesToMatch.put(GraphPropertiesDictionary.USER_STATUS.getProperty(), status);
-			}
-
-			Either<List<UserData>, TitanOperationStatus> userNodes = titanGenericDao.getByCriteria(NodeTypeEnum.User, propertiesToMatch, UserData.class);
-
-			titanGenericDao.commit();
-			return convertToUsers(role, userNodes);
-		} finally {
-			titanGenericDao.commit();
-		}
-	}
-
-	private Either<List<User>, ActionStatus> convertToUsers(String role, Either<List<UserData>, TitanOperationStatus> userNodes) {
-
-		if (userNodes.isRight()) {
+        if (userNodes.isRight()) {
             // in case of NOT_FOUND from Titan return empty list
-            if (userNodes.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
+            TitanOperationStatus tos = userNodes.right().value();
+            if (tos.equals(TitanOperationStatus.NOT_FOUND)) {
                 return Either.left(Collections.emptyList());
             } else {
-                log.error("Problem while getting all users with role {}. Reason - {}", role, userNodes.right().value().name());
+                log.error("Problem while getting all users with role {}. Reason - {}", role, tos);
                 return Either.right(ActionStatus.GENERAL_ERROR);
             }
         } else {
-			List<UserData> userDataList = userNodes.left().value();
+            List<UserData> userDataList = userNodes.left().value();
             if (userDataList != null) {
                 return Either.left(convertToUsers(userDataList));
             }
             log.debug("No users were found with role {}", role);
             return Either.left(Collections.emptyList());
         }
-	}
+    }
 
-	private List<User> convertToUsers(List<UserData> usersData) {
-		List<User> result = new ArrayList<>();
-		for (UserData userData : usersData) {
-			User user = convertToUser(userData);
-			result.add(user);
-		}
-		return result;
-	}
+    private List<User> convertToUsers(List<UserData> usersData) {
+        List<User> result = new ArrayList<>();
+        for (UserData userData : usersData) {
+            User user = convertToUser(userData);
+            result.add(user);
+        }
+        return result;
+    }
 
-	private Either<User, ActionStatus> getUserNotFoundError(String uid, TitanOperationStatus status) {
-		if (status == TitanOperationStatus.NOT_FOUND) {
+    private Either<User, ActionStatus> getUserNotFoundError(String uid, TitanOperationStatus status) {
+        if (status == TitanOperationStatus.NOT_FOUND) {
             log.debug("User with userId {} not found", uid);
             return Either.right(ActionStatus.USER_NOT_FOUND);
         } else {
-            log.debug("Problem get User with userId {}. Reason - {}", uid, status.name());
+            log.debug("Problem get User with userId {}. Reason - {}", uid, status);
             return  Either.right(ActionStatus.GENERAL_ERROR);
         }
-	}
+    }
 
-	protected User convertToUser(UserData userData) {
-		User user = new User();
-		user.setUserId(userData.getUserId());
-		user.setEmail(userData.getEmail());
-		user.setFirstName(userData.getFirstName());
-		user.setLastName(userData.getLastName());
-		user.setRole(userData.getRole());
-		user.setLastLoginTime(userData.getLastLoginTime());
-		// Support backward compatibility - user status may not exist in old
-		// users
-		Either<UserStatusEnum, MethodActivationStatusEnum> either = UserStatusEnum.findByName(userData.getStatus());
-		user.setStatus(either.isLeft() ? either.left().value() : UserStatusEnum.ACTIVE);
-		return user;
-	}
+    protected User convertToUser(UserData userData) {
+        User user = new User();
+        user.setUserId(userData.getUserId());
+        user.setEmail(userData.getEmail());
+        user.setFirstName(userData.getFirstName());
+        user.setLastName(userData.getLastName());
+        user.setRole(userData.getRole());
+        user.setLastLoginTime(userData.getLastLoginTime());
+        // Support backward compatibility - user status may not exist in old
+        // users
+        Either<UserStatusEnum, MethodActivationStatusEnum> either = UserStatusEnum.findByName(userData.getStatus());
+        user.setStatus(either.isLeft() ? either.left().value() : UserStatusEnum.ACTIVE);
+        return user;
+    }
 
-	protected UserData convertToUserData(User user) {
-		UserData userData = new UserData();
-		userData.setUserId(user.getUserId().toLowerCase());
-		userData.setEmail(user.getEmail());
-		userData.setFirstName(user.getFirstName());
-		userData.setLastName(user.getLastName());
-		userData.setRole(user.getRole());
-		userData.setStatus(user.getStatus().name());
-		userData.setLastLoginTime(user.getLastLoginTime());
-		return userData;
-	}
+    protected UserData convertToUserData(User user) {
+        UserData userData = new UserData();
+        userData.setUserId(user.getUserId().toLowerCase());
+        userData.setEmail(user.getEmail());
+        userData.setFirstName(user.getFirstName());
+        userData.setLastName(user.getLastName());
+        userData.setRole(user.getRole());
+        userData.setStatus(user.getStatus().name());
+        userData.setLastLoginTime(user.getLastLoginTime());
+        return userData;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.java
index 2c2d3e7..d4cbc8d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.java
@@ -20,76 +20,74 @@
 
 package org.openecomp.sdc.be.model.operations.utils;
 
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.LifecycleStateEnum;
 import org.openecomp.sdc.be.model.Resource;
 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fj.data.Either;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
 public class ComponentValidationUtils {
 
-	private static Logger log = LoggerFactory.getLogger(ComponentValidationUtils.class.getName());
+    private static final Logger log = Logger.getLogger(ComponentValidationUtils.class.getName());
 
-	public static boolean canWorkOnResource(Resource resource, String userId) {
-		// verify resource is checked-out
-		if (resource.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
-			log.debug("resource is not checked-out");
-			return false;
-		}
-		// verify resource is not deleted
-		if ((resource.getIsDeleted() != null) && (resource.getIsDeleted() == true)) {
-			log.debug("resource is marked as delete");
-			return false;
-		}
-		// verify resource last update user is the current user
-		if (!userId.equals(resource.getLastUpdaterUserId())) {
-			log.debug("resource last update is not {}", userId);
-			return false;
-		}
-		return true;
-	}
+    public static boolean canWorkOnResource(Resource resource, String userId) {
+        // verify resource is checked-out
+        if (resource.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
+            log.debug("resource is not checked-out");
+            return false;
+        }
+        // verify resource is not deleted
+        if ((resource.getIsDeleted() != null) && (resource.getIsDeleted())) {
+            log.debug("resource is marked as delete");
+            return false;
+        }
+        // verify resource last update user is the current user
+        if (!userId.equals(resource.getLastUpdaterUserId())) {
+            log.debug("resource last update is not {}", userId);
+            return false;
+        }
+        return true;
+    }
 
-	public static boolean canWorkOnComponent(String componentId, ToscaOperationFacade toscaOperationFacade, String userId) {
-		
-		Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseMetadata);
+    public static boolean canWorkOnComponent(String componentId, ToscaOperationFacade toscaOperationFacade, String userId) {
 
-		if (getResourceResult.isRight()) {
-			log.debug("Failed to retrieve component, component id {}", componentId);
-			return false;
-		}
-		Component component = getResourceResult.left().value();
+        Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseMetadata);
 
-		return canWorkOnComponent(component, userId);
-	}
-	
-	public static boolean canWorkOnComponent(Component component, String userId) {
-		return canWorkOnComponent(component.getLifecycleState(), component.getLastUpdaterUserId(), userId);
-	}
-	
-	private static boolean canWorkOnComponent(LifecycleStateEnum lifecycleState, String lastUpdaterUserId, String userId) {
-		// verify resource is checked-out
-		if (lifecycleState != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
-			log.debug("resource is not checked-out");
-			return false;
-		}
+        if (getResourceResult.isRight()) {
+            log.debug("Failed to retrieve component, component id {}", componentId);
+            return false;
+        }
+        Component component = getResourceResult.left().value();
 
-		// verify userId is not null
-		if (userId == null) {
-			log.debug("current user userId is null");
-			return false;
-		}
+        return canWorkOnComponent(component, userId);
+    }
 
-		// verify resource last update user is the current user
-		if (!userId.equals(lastUpdaterUserId)) {
-			log.debug("resource last updater userId is not {}", userId);
-			return false;
-		}
-		return true;
-	}
+    public static boolean canWorkOnComponent(Component component, String userId) {
+        return canWorkOnComponent(component.getLifecycleState(), component.getLastUpdaterUserId(), userId);
+    }
+
+    private static boolean canWorkOnComponent(LifecycleStateEnum lifecycleState, String lastUpdaterUserId, String userId) {
+        // verify resource is checked-out
+        if (lifecycleState != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
+            log.debug("resource is not checked-out");
+            return false;
+        }
+
+        // verify userId is not null
+        if (userId == null) {
+            log.debug("current user userId is null");
+            return false;
+        }
+
+        // verify resource last update user is the current user
+        if (!userId.equals(lastUpdaterUserId)) {
+            log.debug("resource last updater userId is not {}", userId);
+            return false;
+        }
+        return true;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/GraphDeleteUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/GraphDeleteUtil.java
deleted file mode 100644
index 1671b2d..0000000
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/GraphDeleteUtil.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*-
- * ============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.be.model.operations.utils;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Element;
-import org.apache.tinkerpop.gremlin.structure.Property;
-import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
-import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
-import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class GraphDeleteUtil {
-
-	private static Logger log = LoggerFactory.getLogger(GraphDeleteUtil.class.getName());
-
-	public TitanOperationStatus deleteChildrenNodes(Vertex rootVertex, GraphEdgeLabels edgeType) {
-
-		// Iterable<Edge> edgesCreatorIterable =
-		// rootVertex.getEdges(Direction.OUT,
-		// edgeType.name());
-		Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty());
-
-		while (edgesCreatorIterator.hasNext()) {
-			Edge edge = edgesCreatorIterator.next();
-			Vertex incomingVertex = edge.inVertex();
-			Iterator<Edge> outEdges = incomingVertex.edges(Direction.OUT);
-
-			if (outEdges.hasNext()) {
-				return TitanOperationStatus.CANNOT_DELETE_NON_LEAF_NODE;
-			} else {
-				Map<String, Object> properties = null;
-				if (log.isDebugEnabled()) {
-					properties = getProperties(incomingVertex);
-					log.debug("Going to delete vertex {}",properties);
-				}
-				incomingVertex.remove();
-				if (log.isDebugEnabled()) {
-					log.debug("After deleting vertex {}",properties);
-				}
-			}
-
-		}
-
-		return TitanOperationStatus.OK;
-
-	}
-
-	public Map<String, Object> getProperties(Element element) {
-
-		Map<String, Object> result = null;
-
-		if (element.keys() != null && element.keys().size() > 0) {
-			Map<String, Property> propertyMap = ElementHelper.propertyMap(element,
-					element.keys().toArray(new String[element.keys().size()]));
-			result = new HashMap<String, Object>();
-
-			for (Entry<String, Property> entry : propertyMap.entrySet()) {
-				String key = entry.getKey();
-				Object value = entry.getValue().value();
-
-				result.put(key, value);
-			}
-		}
-		return result;
-	}
-
-}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java
index ad226f4..a0ff4bc 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java
@@ -20,32 +20,8 @@
 
 package org.openecomp.sdc.be.model.tosca;
 
-import org.openecomp.sdc.be.model.tosca.converters.BooleanConverter;
-import org.openecomp.sdc.be.model.tosca.converters.DefaultConverter;
-import org.openecomp.sdc.be.model.tosca.converters.FloatConverter;
-import org.openecomp.sdc.be.model.tosca.converters.IntegerConverter;
-import org.openecomp.sdc.be.model.tosca.converters.JsonConverter;
-import org.openecomp.sdc.be.model.tosca.converters.ListConverter;
-import org.openecomp.sdc.be.model.tosca.converters.MapConverter;
-import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
-import org.openecomp.sdc.be.model.tosca.converters.StringConvertor;
-import org.openecomp.sdc.be.model.tosca.converters.ToscaBooleanConverter;
-import org.openecomp.sdc.be.model.tosca.converters.ToscaFloatConverter;
-import org.openecomp.sdc.be.model.tosca.converters.ToscaJsonValueConverter;
-import org.openecomp.sdc.be.model.tosca.converters.ToscaListValueConverter;
-import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter;
-import org.openecomp.sdc.be.model.tosca.converters.ToscaStringConvertor;
-import org.openecomp.sdc.be.model.tosca.converters.ToscaValueConverter;
-import org.openecomp.sdc.be.model.tosca.converters.ToscaValueDefaultConverter;
-import org.openecomp.sdc.be.model.tosca.validators.BooleanValidator;
-import org.openecomp.sdc.be.model.tosca.validators.FloatValidator;
-import org.openecomp.sdc.be.model.tosca.validators.IntegerValidator;
-import org.openecomp.sdc.be.model.tosca.validators.JsonValidator;
-import org.openecomp.sdc.be.model.tosca.validators.KeyValidator;
-import org.openecomp.sdc.be.model.tosca.validators.ListValidator;
-import org.openecomp.sdc.be.model.tosca.validators.MapValidator;
-import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
-import org.openecomp.sdc.be.model.tosca.validators.StringValidator;
+import org.openecomp.sdc.be.model.tosca.converters.*;
+import org.openecomp.sdc.be.model.tosca.validators.*;
 
 /**
  * The primitive type that TOSCA YAML supports.
@@ -54,150 +30,142 @@
  */
 public enum ToscaPropertyType {
 
-	Root("tosca.datatypes.Root", null, null, null, true),
+    Root("tosca.datatypes.Root", null, null, null, true),
 
-	STRING("string", StringValidator.getInstance(), StringConvertor.getInstance(), ToscaStringConvertor.getInstance()),
+    STRING("string", StringValidator.getInstance(), StringConvertor.getInstance(), ToscaStringConvertor.getInstance()),
 
-	BOOLEAN("boolean", BooleanValidator.getInstance(), ToscaBooleanConverter.getInstance(), BooleanConverter.getInstance()),
+    BOOLEAN("boolean", BooleanValidator.getInstance(), ToscaBooleanConverter.getInstance(), BooleanConverter.getInstance()),
 
-	FLOAT("float", FloatValidator.getInstance(), ToscaFloatConverter.getInstance(), FloatConverter.getInstance()),
+    FLOAT("float", FloatValidator.getInstance(), ToscaFloatConverter.getInstance(), FloatConverter.getInstance()),
 
-	INTEGER("integer", IntegerValidator.getInstance(), DefaultConverter.getInstance(), IntegerConverter.getInstance()),
-	
-	SCALAR_UNIT("scalar-unit", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
+    INTEGER("integer", IntegerValidator.getInstance(), DefaultConverter.getInstance(), IntegerConverter.getInstance()),
 
-	SCALAR_UNIT_SIZE("scalar-unit.size", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
+    SCALAR_UNIT("scalar-unit", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
 
-	SCALAR_UNIT_TIME("scalar-unit.time", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
+    SCALAR_UNIT_SIZE("scalar-unit.size", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
 
-	SCALAR_UNIT_FREQUENCY("scalar-unit.frequency", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
+    SCALAR_UNIT_TIME("scalar-unit.time", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
 
-	RANGE("range", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
+    SCALAR_UNIT_FREQUENCY("scalar-unit.frequency", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
 
-	TIMESTAMP("timestamp", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
+    RANGE("range", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
 
-	MAP("map", MapValidator.getInstance(), MapConverter.getInstance(), ToscaMapValueConverter.getInstance()),
+    TIMESTAMP("timestamp", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
 
-	LIST("list", ListValidator.getInstance(), ListConverter.getInstance(), ToscaListValueConverter.getInstance()),
+    MAP("map", MapValidator.getInstance(), MapConverter.getInstance(), ToscaMapValueConverter.getInstance()),
 
-	VERSION("version", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
+    LIST("list", ListValidator.getInstance(), ListConverter.getInstance(), ToscaListValueConverter.getInstance()),
 
-	KEY("key", KeyValidator.getInstance(), StringConvertor.getInstance(), ToscaValueDefaultConverter.getInstance()),
+    VERSION("version", StringValidator.getInstance(), DefaultConverter.getInstance(), ToscaValueDefaultConverter.getInstance()),
 
-	JSON("json", JsonValidator.getInstance(), JsonConverter.getInstance(), ToscaJsonValueConverter.getInstance());
+    KEY("key", KeyValidator.getInstance(), StringConvertor.getInstance(), ToscaValueDefaultConverter.getInstance()),
 
-	// CREDENTIAL("tosca.datatypes.Credential", StringValidator.getInstance(),
-	// DefaultConverter.getInstance());
+    JSON("json", JsonValidator.getInstance(), JsonConverter.getInstance(), ToscaJsonValueConverter.getInstance());
 
-	private String type;
-	private PropertyTypeValidator validator;
-	private PropertyValueConverter converter;
-	private ToscaValueConverter valueConverter;
-	private boolean isAbstract = false;
+    private String type;
+    private PropertyTypeValidator validator;
+    private PropertyValueConverter converter;
+    private ToscaValueConverter valueConverter;
+    private boolean isAbstract = false;
 
-	ToscaPropertyType(String type, PropertyTypeValidator validator, PropertyValueConverter converter, ToscaValueConverter valueConverter) {
-		this.type = type;
-		this.validator = validator;
-		this.converter = converter;
-		this.valueConverter = valueConverter;
-	}
+    ToscaPropertyType(String type, PropertyTypeValidator validator, PropertyValueConverter converter, ToscaValueConverter valueConverter) {
+        this.type = type;
+        this.validator = validator;
+        this.converter = converter;
+        this.valueConverter = valueConverter;
+    }
 
-	ToscaPropertyType(String type, PropertyTypeValidator validator, PropertyValueConverter converter, ToscaValueConverter valueConverter, boolean isAbstract) {
-		this(type, validator, converter, valueConverter);
-		this.isAbstract = isAbstract;
-	}
+    ToscaPropertyType(String type, PropertyTypeValidator validator, PropertyValueConverter converter, ToscaValueConverter valueConverter, boolean isAbstract) {
+        this(type, validator, converter, valueConverter);
+        this.isAbstract = isAbstract;
+    }
 
-	// private static final Pattern TIMESTAMP_REGEX = Pattern
-	// .compile("[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?([Tt]|[
-	// \\t]+)[0-9][0-9]?:[0-9][0-9]:[0-9][0-9](\\.[0-9]*)?(([ \\t]*)Z|([
-	// \\t]*)[-+][0-9][0-9]?(:[0-9][0-9])?)?");
+    public String getType() {
+        return type;
+    }
 
-	public String getType() {
-		return type;
-	}
+    public void setType(String type) {
+        this.type = type;
+    }
 
-	public void setType(String type) {
-		this.type = type;
-	}
+    public PropertyTypeValidator getValidator() {
+        return validator;
+    }
 
-	public PropertyTypeValidator getValidator() {
-		return validator;
-	}
+    public void setValidator(PropertyTypeValidator validator) {
+        this.validator = validator;
+    }
 
-	public void setValidator(PropertyTypeValidator validator) {
-		this.validator = validator;
-	}
+    public PropertyValueConverter getConverter() {
+        return converter;
+    }
 
-	public PropertyValueConverter getConverter() {
-		return converter;
-	}
+    public void setConverter(PropertyValueConverter converter) {
+        this.converter = converter;
+    }
 
-	public void setConverter(PropertyValueConverter converter) {
-		this.converter = converter;
-	}
+    public boolean isAbstract() {
+        return isAbstract;
+    }
 
-	public boolean isAbstract() {
-		return isAbstract;
-	}
+    public void setAbstract(boolean isAbstract) {
+        this.isAbstract = isAbstract;
+    }
 
-	public void setAbstract(boolean isAbstract) {
-		this.isAbstract = isAbstract;
-	}
+    public ToscaValueConverter getValueConverter() {
+        return valueConverter;
+    }
 
-	public ToscaValueConverter getValueConverter() {
-		return valueConverter;
-	}
+    public void setValueConverter(ToscaValueConverter valueConverter) {
+        this.valueConverter = valueConverter;
+    }
 
-	public void setValueConverter(ToscaValueConverter valueConverter) {
-		this.valueConverter = valueConverter;
-	}
+    public static ToscaPropertyType isValidType(String typeName) {
+        if (typeName == null) {
+            return null;
+        }
 
-	public static ToscaPropertyType isValidType(String typeName) {
-		if (typeName == null) {
-			return null;
-		}
+        for (ToscaPropertyType type : ToscaPropertyType.values()) {
+            if (type.getType().equals(typeName)) {
+                return type;
+            }
+        }
+        return null;
+    }
 
-		for (ToscaPropertyType type : ToscaPropertyType.values()) {
-			if (type.getType().equals(typeName)) {
-				return type;
-			}
-		}
-		return null;
-	}
+    public static boolean isScalarType(String dataTypeName) {
 
-	public static boolean isScalarType(String dataTypeName) {
+        ToscaPropertyType isPrimitiveToscaType = ToscaPropertyType.isValidType(dataTypeName);
 
-		ToscaPropertyType isPrimitiveToscaType = ToscaPropertyType.isValidType(dataTypeName);
+        return isPrimitiveToscaType != null && !isPrimitiveToscaType.isAbstract();
 
-		return isPrimitiveToscaType != null && isPrimitiveToscaType.isAbstract() == false;
+    }
 
-	}
-	
-	public static boolean isPrimitiveType(String dataTypeName) {
-		
-		if (ToscaPropertyType.MAP.getType().equals(dataTypeName) || ToscaPropertyType.LIST.getType().equals(dataTypeName)){
-			return false;
-		}
-		if(isScalarType(dataTypeName)){
-			return true;
-		}
-		return false;
-	}
+    public static boolean isPrimitiveType(String dataTypeName) {
 
-	public static ToscaPropertyType getTypeIfScalar(String dataTypeName) {
+        if (ToscaPropertyType.MAP.getType().equals(dataTypeName) || ToscaPropertyType.LIST.getType().equals(dataTypeName)){
+            return false;
+        }
+        if(isScalarType(dataTypeName)){
+            return true;
+        }
+        return false;
+    }
 
-		ToscaPropertyType isPrimitiveToscaType = ToscaPropertyType.isValidType(dataTypeName);
+    public static ToscaPropertyType getTypeIfScalar(String dataTypeName) {
 
-		if (isPrimitiveToscaType != null && isPrimitiveToscaType.isAbstract() == false) {
-			return isPrimitiveToscaType;
-		} else {
-			return null;
-		}
+        ToscaPropertyType isPrimitiveToscaType = ToscaPropertyType.isValidType(dataTypeName);
 
-	}
+        if (isPrimitiveToscaType != null && !isPrimitiveToscaType.isAbstract()) {
+            return isPrimitiveToscaType;
+        } else {
+            return null;
+        }
 
-	@Override
-	public String toString() {
-		return name().toLowerCase();
-	}
+    }
+
+    @Override
+    public String toString() {
+        return name().toLowerCase();
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java
index 88642f8..92c564c 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java
@@ -30,91 +30,75 @@
  * @author mkv
  */
 public enum ToscaType {
-	STRING, INTEGER, FLOAT, BOOLEAN, TIMESTAMP, VERSION;
+    STRING, INTEGER, FLOAT, BOOLEAN, TIMESTAMP, VERSION;
 
-	// private static final Pattern TIMESTAMP_REGEX = Pattern
-	// .compile("[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?([Tt]|[
-	// \\t]+)[0-9][0-9]?:[0-9][0-9]:[0-9][0-9](\\.[0-9]*)?(([ \\t]*)Z|([
-	// \\t]*)[-+][0-9][0-9]?(:[0-9][0-9])?)?");
+    public boolean isValidValue(String value) {
+        switch (this) {
+        case BOOLEAN:
+            return value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false");
+        case FLOAT:
+            return isFloat(value);
+        case INTEGER:
+            return isInteger(value);
+        case STRING:
+            return true;
+        case TIMESTAMP:
+            try {
+                DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).parse(value);
+                return true;
+            } catch (ParseException e) {
+                return false;
+            }
+        case VERSION:
+            return VersionUtil.isValid(value);
+        default:
+            return false;
+        }
+    }
 
-	public static ToscaType fromYamlTypeName(String typeName) {
-		if (typeName == null) {
-			return null;
-		}
-		try {
-			return ToscaType.valueOf(typeName.toUpperCase());
-		} catch (IllegalArgumentException e) {
-			return null;
-		}
-	}
+    private boolean isFloat(String value) {
+        try {
+            Float.valueOf(value);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+        return true;
+    }
 
-	public boolean isValidValue(String value) {
-		switch (this) {
-		case BOOLEAN:
-			return value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false");
-		case FLOAT:
-			return isFloat(value);
-		case INTEGER:
-			return isInteger(value);
-		case STRING:
-			return true;
-		case TIMESTAMP:
-			try {
-				DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).parse(value);
-				return true;
-			} catch (ParseException e) {
-				return false;
-			}
-		case VERSION:
-			return VersionUtil.isValid(value);
-		default:
-			return false;
-		}
-	}
+    private boolean isInteger(String value) {
+        try {
+            Long.valueOf(value);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+        return true;
+    }
 
-	private boolean isFloat(String value) {
-		try {
-			Float.valueOf(value);
-		} catch (NumberFormatException e) {
-			return false;
-		}
-		return true;
-	}
+    public Object convert(String value) {
+        switch (this) {
+        case STRING:
+            return value;
+        case BOOLEAN:
+            return Boolean.valueOf(value);
+        case FLOAT:
+            return Double.valueOf(value);
+        case INTEGER:
+            return Long.valueOf(value);
+        case TIMESTAMP:
+            try {
+                return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).parse(value);
+            } catch (ParseException e) {
+                throw new IllegalArgumentException("Value must be a valid timestamp", e);
+            }
+        case VERSION:
+            return VersionUtil.parseVersion(value);
+        default:
+            return null;
+        }
+    }
 
-	private boolean isInteger(String value) {
-		try {
-			Long.valueOf(value);
-		} catch (NumberFormatException e) {
-			return false;
-		}
-		return true;
-	}
-
-	public Object convert(String value) {
-		switch (this) {
-		case STRING:
-			return value;
-		case BOOLEAN:
-			return Boolean.valueOf(value);
-		case FLOAT:
-			return Double.valueOf(value);
-		case INTEGER:
-			return Long.valueOf(value);
-		case TIMESTAMP:
-			try {
-				return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).parse(value);
-			} catch (ParseException e) {
-				throw new IllegalArgumentException("Value must be a valid timestamp", e);
-			}
-		case VERSION:
-			return VersionUtil.parseVersion(value);
-		default:
-			return null;
-		}
-	}
-
-	@Override
-	public String toString() {
-		return name().toLowerCase();
-	}
+    @Override
+    public String toString() {
+        return name().toLowerCase();
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.java
index 91d806e..41b7a2e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.java
@@ -20,75 +20,75 @@
 
 package org.openecomp.sdc.be.model.tosca;
 
-import java.util.regex.Pattern;
-
 import org.openecomp.sdc.be.model.tosca.version.ApplicationVersionException;
 import org.openecomp.sdc.be.model.tosca.version.Version;
 
+import java.util.regex.Pattern;
+
 public final class VersionUtil {
 
-	/** Utility class should not have public constructor. */
-	private VersionUtil() {
-	}
+    /** Utility class should not have public constructor. */
+    private VersionUtil() {
+    }
 
-	/**
-	 * The version must begin with a bloc of numbers, and then it can have one
-	 * or more bloc of numbers separated by '.' and then it can have alpha
-	 * numeric bloc separated by '.' or '-'
-	 */
-	public static final Pattern VERSION_PATTERN = Pattern.compile("\\d+(?:\\.\\d+)*(?:[\\.-]\\p{Alnum}+)*");
-	private static final String SNAPSHOT_IDENTIFIER = "SNAPSHOT";
+    /**
+     * The version must begin with a bloc of numbers, and then it can have one
+     * or more bloc of numbers separated by '.' and then it can have alpha
+     * numeric bloc separated by '.' or '-'
+     */
+    public static final Pattern VERSION_PATTERN = Pattern.compile("\\d+(?:\\.\\d+)*(?:[\\.-]\\p{Alnum}+)*");
+    private static final String SNAPSHOT_IDENTIFIER = "SNAPSHOT";
 
-	/**
-	 * Check if a version is a SNAPSHOT (development) version.
-	 * 
-	 * @param version
-	 *            The actual version string.
-	 * @return True if the version is a SNAPSHOT version, false if not (RELEASE
-	 *         version).
-	 */
-	public static boolean isSnapshot(String version) {
-		return version.toUpperCase().contains(SNAPSHOT_IDENTIFIER);
-	}
+    /**
+     * Check if a version is a SNAPSHOT (development) version.
+     *
+     * @param version
+     *            The actual version string.
+     * @return True if the version is a SNAPSHOT version, false if not (RELEASE
+     *         version).
+     */
+    public static boolean isSnapshot(String version) {
+        return version.toUpperCase().contains(SNAPSHOT_IDENTIFIER);
+    }
 
-	/**
-	 * Check if a version is valid
-	 * 
-	 * @param version
-	 *            version string to parse
-	 * @return true if it's following the defined version pattern
-	 */
-	public static boolean isValid(String version) {
-		return VERSION_PATTERN.matcher(version).matches();
-	}
+    /**
+     * Check if a version is valid
+     *
+     * @param version
+     *            version string to parse
+     * @return true if it's following the defined version pattern
+     */
+    public static boolean isValid(String version) {
+        return VERSION_PATTERN.matcher(version).matches();
+    }
 
-	/**
-	 * Parse the version's text to produce a comparable version object
-	 * 
-	 * @param version
-	 *            version text to parse
-	 * @return a comparable version object
-	 * @throws ApplicationVersionException
-	 *             if the version text is not following the defined version
-	 *             pattern
-	 */
-	public static Version parseVersion(String version) {
-		if (!isValid(version)) {
-			throw new ApplicationVersionException(
-					"This version is not valid [" + version + "] as it does not match [" + VERSION_PATTERN + "]");
-		} else {
-			return new Version(version);
-		}
-	}
+    /**
+     * Parse the version's text to produce a comparable version object
+     *
+     * @param version
+     *            version text to parse
+     * @return a comparable version object
+     * @throws ApplicationVersionException
+     *             if the version text is not following the defined version
+     *             pattern
+     */
+    public static Version parseVersion(String version) {
+        if (!isValid(version)) {
+            throw new ApplicationVersionException(
+                    "This version is not valid [" + version + "] as it does not match [" + VERSION_PATTERN + "]");
+        } else {
+            return new Version(version);
+        }
+    }
 
-	/**
-	 * Compare 2 versions
-	 * 
-	 * @param versionLeft
-	 * @param versionRight
-	 * @return
-	 */
-	public static int compare(String versionLeft, String versionRight) {
-		return parseVersion(versionLeft).compareTo(parseVersion(versionRight));
-	}
+    /**
+     * Compare 2 versions
+     *
+     * @param versionLeft
+     * @param versionRight
+     * @return
+     */
+    public static int compare(String versionLeft, String versionRight) {
+        return parseVersion(versionLeft).compareTo(parseVersion(versionRight));
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.java
index 7b46692..1611356 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.java
@@ -20,53 +20,46 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
 @SuppressWarnings("rawtypes")
-public abstract class AbstractComparablePropertyConstraint extends AbstractPropertyConstraint implements Serializable {
+public abstract class AbstractComparablePropertyConstraint extends AbstractPropertyConstraint {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 2002627754053326321L;
+    private Comparable comparable;
 
-	private Comparable comparable;
+    protected Comparable getComparable() {
+        return comparable;
+    }
 
-	protected Comparable getComparable() {
-		return comparable;
-	}
+    protected void initialize(String rawTextValue, ToscaType propertyType)
+            throws ConstraintValueDoNotMatchPropertyTypeException {
+        // Perform verification that the property type is supported for
+        // comparison
+        ConstraintUtil.checkComparableType(propertyType);
+        // Check if the text value is valid for the property type
+        if (propertyType.isValidValue(rawTextValue)) {
+            // Convert the raw text value to a comparable value
+            comparable = ConstraintUtil.convertToComparable(propertyType, rawTextValue);
+        } else {
+            // Invalid value throw exception
+            throw new ConstraintValueDoNotMatchPropertyTypeException(
+                    "The value [" + rawTextValue + "] is not valid for the type [" + propertyType + "]");
+        }
+    }
 
-	protected void initialize(String rawTextValue, ToscaType propertyType)
-			throws ConstraintValueDoNotMatchPropertyTypeException {
-		// Perform verification that the property type is supported for
-		// comparison
-		ConstraintUtil.checkComparableType(propertyType);
-		// Check if the text value is valid for the property type
-		if (propertyType.isValidValue(rawTextValue)) {
-			// Convert the raw text value to a comparable value
-			comparable = ConstraintUtil.convertToComparable(propertyType, rawTextValue);
-		} else {
-			// Invalid value throw exception
-			throw new ConstraintValueDoNotMatchPropertyTypeException(
-					"The value [" + rawTextValue + "] is not valid for the type [" + propertyType + "]");
-		}
-	}
+    protected abstract void doValidate(Object propertyValue) throws ConstraintViolationException;
 
-	protected abstract void doValidate(Object propertyValue) throws ConstraintViolationException;
-
-	@Override
-	public void validate(Object propertyValue) throws ConstraintViolationException {
-		if (propertyValue == null) {
-			throw new ConstraintViolationException("Value to check is null");
-		}
-		if (!(comparable.getClass().isAssignableFrom(propertyValue.getClass()))) {
-			throw new ConstraintViolationException("Value to check is not comparable to reference type, value type ["
-					+ propertyValue.getClass() + "], reference type [" + comparable.getClass() + "]");
-		}
-		doValidate(propertyValue);
-	}
+    @Override
+    public void validate(Object propertyValue) throws ConstraintViolationException {
+        if (propertyValue == null) {
+            throw new ConstraintViolationException("Value to check is null");
+        }
+        if (!(comparable.getClass().isAssignableFrom(propertyValue.getClass()))) {
+            throw new ConstraintViolationException("Value to check is not comparable to reference type, value type ["
+                    + propertyValue.getClass() + "], reference type [" + comparable.getClass() + "]");
+        }
+        doValidate(propertyValue);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.java
index 950a7fa..fc96373 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.java
@@ -20,27 +20,20 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-
 import org.openecomp.sdc.be.model.PropertyConstraint;
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 import org.openecomp.sdc.be.model.tosca.version.ApplicationVersionException;
 
-public abstract class AbstractPropertyConstraint implements PropertyConstraint, Serializable {
+public abstract class AbstractPropertyConstraint implements PropertyConstraint {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 4459522275459723374L;
-
-	@Override
-	public void validate(ToscaType toscaType, String propertyTextValue) throws ConstraintViolationException {
-		try {
-			validate(toscaType.convert(propertyTextValue));
-		} catch (IllegalArgumentException | ApplicationVersionException e) {
-			throw new ConstraintViolationException(
-					"String value [" + propertyTextValue + "] is not valid for type [" + toscaType + "]", e);
-		}
-	}
+    @Override
+    public void validate(ToscaType toscaType, String propertyTextValue) throws ConstraintViolationException {
+        try {
+            validate(toscaType.convert(propertyTextValue));
+        } catch (IllegalArgumentException | ApplicationVersionException e) {
+            throw new ConstraintViolationException(
+                    "String value [" + propertyTextValue + "] is not valid for type [" + toscaType + "]", e);
+        }
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.java
index 142caa2..8f54c68 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.java
@@ -20,34 +20,27 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
-public abstract class AbstractStringPropertyConstraint extends AbstractPropertyConstraint implements Serializable {
+public abstract class AbstractStringPropertyConstraint extends AbstractPropertyConstraint {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 6857605164938136232L;
+    protected abstract void doValidate(String propertyValue) throws ConstraintViolationException;
 
-	protected abstract void doValidate(String propertyValue) throws ConstraintViolationException;
+    @Override
+    public void validate(Object propertyValue) throws ConstraintViolationException {
+        if (propertyValue == null) {
+            throw new ConstraintViolationException("Value to validate is null");
+        }
+        if (!(propertyValue instanceof String)) {
+            throw new ConstraintViolationException("This constraint can only be applied on String value");
+        }
+        doValidate((String) propertyValue);
+    }
 
-	@Override
-	public void validate(Object propertyValue) throws ConstraintViolationException {
-		if (propertyValue == null) {
-			throw new ConstraintViolationException("Value to validate is null");
-		}
-		if (!(propertyValue instanceof String)) {
-			throw new ConstraintViolationException("This constraint can only be applied on String value");
-		}
-		doValidate((String) propertyValue);
-	}
-
-	@Override
-	public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
-		ConstraintUtil.checkStringType(propertyType);
-	}
+    @Override
+    public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
+        ConstraintUtil.checkStringType(propertyType);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java
index 5f19d15..c78afd8 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java
@@ -25,36 +25,36 @@
 
 public enum ConstraintType {
 
-	IN_RANGE("inRange"),
+    IN_RANGE("inRange"),
 
-	GREATER_THAN("greaterThan", "greater_than"),
+    GREATER_THAN("greaterThan", "greater_than"),
 
-	GREATER_OR_EQUAL("greaterOrEqual", "greater_or_equal"),
+    GREATER_OR_EQUAL("greaterOrEqual", "greater_or_equal"),
 
-	LESS_OR_EQUAL("lessOrEqual", "less_or_equal"),
+    LESS_OR_EQUAL("lessOrEqual", "less_or_equal"),
 
-	MIN_LENGTH("minLength", "min_length"),
+    MIN_LENGTH("minLength", "min_length"),
 
-	VALID_VALUES("validValues", "valid_values"),
+    VALID_VALUES("validValues", "valid_values"),
 
-	LESS_THAN("lessThan", "less_than");
+    LESS_THAN("lessThan", "less_than");
 
-	List<String> types;
+    List<String> types;
 
-	private ConstraintType(String... types) {
-		this.types = Arrays.asList(types);
-	}
+    private ConstraintType(String... types) {
+        this.types = Arrays.asList(types);
+    }
 
-	public List<String> getTypes() {
-		return types;
-	}
+    public List<String> getTypes() {
+        return types;
+    }
 
-	public static ConstraintType getByType(String type) {
-		for (ConstraintType inst : ConstraintType.values()) {
-			if (inst.getTypes().contains(type)) {
-				return inst;
-			}
-		}
-		return null;
-	}
+    public static ConstraintType getByType(String type) {
+        for (ConstraintType inst : ConstraintType.values()) {
+            if (inst.getTypes().contains(type)) {
+                return inst;
+            }
+        }
+        return null;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.java
index 79ac5ca..3c1f0ab 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.java
@@ -20,126 +20,126 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
+import org.openecomp.sdc.be.model.tosca.ToscaType;
+import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
+
 import java.beans.IntrospectionException;
 import java.beans.Introspector;
 import java.beans.PropertyDescriptor;
 import java.lang.reflect.InvocationTargetException;
 
-import org.openecomp.sdc.be.model.tosca.ToscaType;
-import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
-
 /**
  * Utility class to validate constraints types.
  */
 public final class ConstraintUtil {
 
-	private ConstraintUtil() {
-	}
+    private ConstraintUtil() {
+    }
 
-	/**
-	 * Validates that the {@link ToscaType} specified is a
-	 * {@link ToscaType#STRING}.
-	 * 
-	 * @param propertyType
-	 *            The property tosca type.
-	 * @throws ConstraintValueDoNotMatchPropertyTypeException
-	 *             In case the type is not {@link ToscaType#STRING}.
-	 */
-	public static void checkStringType(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
-		if (!ToscaType.STRING.equals(propertyType)) {
-			throw new ConstraintValueDoNotMatchPropertyTypeException(
-					"Invalid property type <" + propertyType.toString() + ">");
-		}
-	}
+    /**
+     * Validates that the {@link ToscaType} specified is a
+     * {@link ToscaType#STRING}.
+     *
+     * @param propertyType
+     *            The property tosca type.
+     * @throws ConstraintValueDoNotMatchPropertyTypeException
+     *             In case the type is not {@link ToscaType#STRING}.
+     */
+    public static void checkStringType(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
+        if (!ToscaType.STRING.equals(propertyType)) {
+            throw new ConstraintValueDoNotMatchPropertyTypeException(
+                    "Invalid property type <" + propertyType.toString() + ">");
+        }
+    }
 
-	/**
-	 * Verify that the given tosca type is supported for comparison
-	 * 
-	 * @param propertyType
-	 *            the tosca type to check
-	 * @throws ConstraintValueDoNotMatchPropertyTypeException
-	 *             if the property type cannot be compared
-	 */
-	public static void checkComparableType(ToscaType propertyType)
-			throws ConstraintValueDoNotMatchPropertyTypeException {
-		// The validity of the value is already assured by us with our
-		// ToscaType.convert() method
-		// here we just want to check that the constraint is not used on
-		// unsupported type as boolean
-		switch (propertyType) {
-		case FLOAT:
-		case INTEGER:
-		case TIMESTAMP:
-		case VERSION:
-			break;
-		case STRING:
-		case BOOLEAN:
-			throw new ConstraintValueDoNotMatchPropertyTypeException(
-					"Constraint is invalid for property type <" + propertyType.toString() + ">");
-		default:
-			throw new ConstraintValueDoNotMatchPropertyTypeException(
-					"Invalid property type <" + propertyType.toString() + ">");
-		}
-	}
+    /**
+     * Verify that the given tosca type is supported for comparison
+     *
+     * @param propertyType
+     *            the tosca type to check
+     * @throws ConstraintValueDoNotMatchPropertyTypeException
+     *             if the property type cannot be compared
+     */
+    public static void checkComparableType(ToscaType propertyType)
+            throws ConstraintValueDoNotMatchPropertyTypeException {
+        // The validity of the value is already assured by us with our
+        // ToscaType.convert() method
+        // here we just want to check that the constraint is not used on
+        // unsupported type as boolean
+        switch (propertyType) {
+        case FLOAT:
+        case INTEGER:
+        case TIMESTAMP:
+        case VERSION:
+            break;
+        case STRING:
+        case BOOLEAN:
+            throw new ConstraintValueDoNotMatchPropertyTypeException(
+                    "Constraint is invalid for property type <" + propertyType.toString() + ">");
+        default:
+            throw new ConstraintValueDoNotMatchPropertyTypeException(
+                    "Invalid property type <" + propertyType.toString() + ">");
+        }
+    }
 
-	/**
-	 * Convert a string value following its type throw exception if it cannot be
-	 * converted to a comparable
-	 * 
-	 * @param propertyType
-	 *            the type of the property
-	 * @param value
-	 *            the value to convert
-	 * @return the converted comparable
-	 * @throws ConstraintValueDoNotMatchPropertyTypeException
-	 *             if the converted value is not a comparable
-	 */
-	@SuppressWarnings("rawtypes")
-	public static Comparable convertToComparable(ToscaType propertyType, String value)
-			throws ConstraintValueDoNotMatchPropertyTypeException {
-		Object comparableObj = propertyType.convert(value);
-		if (!(comparableObj instanceof Comparable)) {
-			throw new IllegalArgumentException(
-					"Try to convert a value of a type which is not comparable [" + propertyType + "] to Comparable");
-		} else {
-			return (Comparable) comparableObj;
-		}
-	}
+    /**
+     * Convert a string value following its type throw exception if it cannot be
+     * converted to a comparable
+     *
+     * @param propertyType
+     *            the type of the property
+     * @param value
+     *            the value to convert
+     * @return the converted comparable
+     * @throws ConstraintValueDoNotMatchPropertyTypeException
+     *             if the converted value is not a comparable
+     */
+    @SuppressWarnings("rawtypes")
+    public static Comparable convertToComparable(ToscaType propertyType, String value)
+            throws ConstraintValueDoNotMatchPropertyTypeException {
+        Object comparableObj = propertyType.convert(value);
+        if (!(comparableObj instanceof Comparable)) {
+            throw new IllegalArgumentException(
+                    "Try to convert a value of a type which is not comparable [" + propertyType + "] to Comparable");
+        } else {
+            return (Comparable) comparableObj;
+        }
+    }
 
-	public static class ConstraintInformation {
-		public ConstraintInformation(String name, Object reference, String value, String type) {
+    public static class ConstraintInformation {
+        public ConstraintInformation(String name, Object reference, String value, String type) {
 
-			this.name = name;
-			this.reference = reference;
-			this.value = value;
-			this.type = type;
+            this.name = name;
+            this.reference = reference;
+            this.value = value;
+            this.type = type;
 
-		}
+        }
 
-		private String name;
-		private Object reference;
-		private String value;
-		private String type;
-	}
+        private String name;
+        private Object reference;
+        private String value;
+        private String type;
+    }
 
-	public static ConstraintInformation getConstraintInformation(Object constraint) throws IntrospectionException {
-		PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(constraint.getClass())
-				.getPropertyDescriptors();
-		PropertyDescriptor firstDescriptor = null;
-		for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
-			if (propertyDescriptor.getReadMethod() != null && propertyDescriptor.getWriteMethod() != null) {
-				firstDescriptor = propertyDescriptor;
-				break;
-			}
-		}
-		if (firstDescriptor == null) {
-			throw new IntrospectionException("Cannot find constraint name");
-		}
-		try {
-			return new ConstraintInformation(firstDescriptor.getName(),
-					firstDescriptor.getReadMethod().invoke(constraint), null, null);
-		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-			throw new IntrospectionException("Cannot retrieve constraint reference " + e.getMessage());
-		}
-	}
+    public static ConstraintInformation getConstraintInformation(Object constraint) throws IntrospectionException {
+        PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(constraint.getClass())
+                .getPropertyDescriptors();
+        PropertyDescriptor firstDescriptor = null;
+        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+            if (propertyDescriptor.getReadMethod() != null && propertyDescriptor.getWriteMethod() != null) {
+                firstDescriptor = propertyDescriptor;
+                break;
+            }
+        }
+        if (firstDescriptor == null) {
+            throw new IntrospectionException("Cannot find constraint name");
+        }
+        try {
+            return new ConstraintInformation(firstDescriptor.getName(),
+                    firstDescriptor.getReadMethod().invoke(constraint), null, null);
+        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            throw new IntrospectionException("Cannot retrieve constraint reference " + e.getMessage());
+        }
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java
index 530dcb0..7ae64e0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java
@@ -20,58 +20,50 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-
-import javax.validation.constraints.NotNull;
-
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
-//import com.fasterxml.jackson.annotation.JsonIgnore;
+import javax.validation.constraints.NotNull;
 
-public class EqualConstraint extends AbstractPropertyConstraint implements Serializable {
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -1596093341744641483L;
+public class EqualConstraint extends AbstractPropertyConstraint {
 
-	@NotNull
-	private String equal;
+    @NotNull
+    private String equal;
 
-	// @JsonIgnore
-	private Object typed;
+    // @JsonIgnore
+    private Object typed;
 
-	public EqualConstraint(String equal) {
-		super();
-		this.equal = equal;
-	}
+    public EqualConstraint(String equal) {
+        super();
+        this.equal = equal;
+    }
 
-	@Override
-	public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
-		if (propertyType.isValidValue(equal)) {
-			typed = propertyType.convert(equal);
-		} else {
-			throw new ConstraintValueDoNotMatchPropertyTypeException("equal constraint has invalid value <" + equal
-					+ "> property type is <" + propertyType.toString() + ">");
-		}
-	}
+    @Override
+    public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
+        if (propertyType.isValidValue(equal)) {
+            typed = propertyType.convert(equal);
+        } else {
+            throw new ConstraintValueDoNotMatchPropertyTypeException("equal constraint has invalid value <" + equal
+                    + "> property type is <" + propertyType.toString() + ">");
+        }
+    }
 
-	@Override
-	public void validate(Object propertyValue) throws ConstraintViolationException {
-		if (propertyValue == null) {
-			if (typed != null) {
-				fail(null);
-			}
-		} else if (typed == null) {
-			fail(propertyValue);
-		} else if (!typed.equals(propertyValue)) {
-			fail(propertyValue);
-		}
-	}
+    @Override
+    public void validate(Object propertyValue) throws ConstraintViolationException {
+        if (propertyValue == null) {
+            if (typed != null) {
+                fail(null);
+            }
+        } else if (typed == null) {
+            fail(propertyValue);
+        } else if (!typed.equals(propertyValue)) {
+            fail(propertyValue);
+        }
+    }
 
-	private void fail(Object propertyValue) throws ConstraintViolationException {
-		throw new ConstraintViolationException("Equal constraint violation, the reference is <" + equal
-				+ "> but the value to compare is <" + propertyValue + ">");
-	}
+    private void fail(Object propertyValue) throws ConstraintViolationException {
+        throw new ConstraintViolationException("Equal constraint violation, the reference is <" + equal
+                + "> but the value to compare is <" + propertyValue + ">");
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java
index 4f2c3ad..63d7ed8 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java
@@ -20,37 +20,30 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-
-import javax.validation.constraints.NotNull;
-
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
-public class GreaterOrEqualConstraint extends AbstractComparablePropertyConstraint implements Serializable {
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -5937851077034490609L;
+import javax.validation.constraints.NotNull;
 
-	@NotNull
-	private String greaterOrEqual;
+public class GreaterOrEqualConstraint extends AbstractComparablePropertyConstraint {
 
-	public GreaterOrEqualConstraint(String greaterOrEqual) {
-		super();
-		this.greaterOrEqual = greaterOrEqual;
-	}
+    @NotNull
+    private String greaterOrEqual;
 
-	@Override
-	public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
-		initialize(greaterOrEqual, propertyType);
-	}
+    public GreaterOrEqualConstraint(String greaterOrEqual) {
+        this.greaterOrEqual = greaterOrEqual;
+    }
 
-	@Override
-	protected void doValidate(Object propertyValue) throws ConstraintViolationException {
-		if (getComparable().compareTo(propertyValue) > 0) {
-			throw new ConstraintViolationException(propertyValue + " <= " + greaterOrEqual);
-		}
-	}
+    @Override
+    public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
+        initialize(greaterOrEqual, propertyType);
+    }
+
+    @Override
+    protected void doValidate(Object propertyValue) throws ConstraintViolationException {
+        if (getComparable().compareTo(propertyValue) > 0) {
+            throw new ConstraintViolationException(propertyValue + " <= " + greaterOrEqual);
+        }
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java
index aea2a20..b599a16 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java
@@ -20,47 +20,39 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-
-import javax.validation.constraints.NotNull;
-
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
-public class GreaterThanConstraint extends AbstractComparablePropertyConstraint implements Serializable {
+import javax.validation.constraints.NotNull;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 405723215512121896L;
+public class GreaterThanConstraint extends AbstractComparablePropertyConstraint {
 
-	public GreaterThanConstraint(String greaterThan) {
-		super();
-		this.greaterThan = greaterThan;
-	}
+    public GreaterThanConstraint(String greaterThan) {
+        this.greaterThan = greaterThan;
+    }
 
-	@NotNull
-	private String greaterThan;
+    @NotNull
+    private String greaterThan;
 
-	@Override
-	public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
-		initialize(greaterThan, propertyType);
-	}
+    @Override
+    public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
+        initialize(greaterThan, propertyType);
+    }
 
-	@Override
-	protected void doValidate(Object propertyValue) throws ConstraintViolationException {
-		if (getComparable().compareTo(propertyValue) >= 0) {
-			throw new ConstraintViolationException(propertyValue + " < " + greaterThan);
-		}
-	}
+    @Override
+    protected void doValidate(Object propertyValue) throws ConstraintViolationException {
+        if (getComparable().compareTo(propertyValue) >= 0) {
+            throw new ConstraintViolationException(propertyValue + " < " + greaterThan);
+        }
+    }
 
-	public String getGreaterThan() {
-		return greaterThan;
-	}
+    public String getGreaterThan() {
+        return greaterThan;
+    }
 
-	public void setGreaterThan(String greaterThan) {
-		this.greaterThan = greaterThan;
-	}
+    public void setGreaterThan(String greaterThan) {
+        this.greaterThan = greaterThan;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java
index e8821c2..19a2fe4 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java
@@ -20,111 +20,95 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-import java.util.List;
-
-import javax.validation.constraints.NotNull;
-
+import com.google.common.collect.Lists;
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
-//import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.collect.Lists;
+import javax.validation.constraints.NotNull;
+import java.util.List;
 
-public class InRangeConstraint extends AbstractPropertyConstraint implements Serializable {
+public class InRangeConstraint extends AbstractPropertyConstraint {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -8038401707152824493L;
+    private List<String> inRange;
 
-	private List<String> inRange;
+    private Comparable min;
+    private Comparable max;
 
-	private Comparable min;
-	private Comparable max;
+    public InRangeConstraint(List<String> inRange) {
+        this.inRange = inRange;
+    }
 
-	public InRangeConstraint(List<String> inRange) {
-		super();
-		this.inRange = inRange;
-	}
+    public InRangeConstraint() { }
 
-	public InRangeConstraint() {
-		super();
-	}
+    @Override
+    public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
+        // Perform verification that the property type is supported for
+        // comparison
+        ConstraintUtil.checkComparableType(propertyType);
+        if (inRange == null || inRange.size() != 2) {
+            throw new ConstraintValueDoNotMatchPropertyTypeException("In range constraint must have two elements.");
+        }
+        String minRawText = inRange.get(0);
+        String maxRawText = inRange.get(1);
+        if (!propertyType.isValidValue(minRawText)) {
+            throw new ConstraintValueDoNotMatchPropertyTypeException("Invalid min value for in range constraint ["
+                    + minRawText + "] as it does not follow the property type [" + propertyType + "]");
+        }
+        if (!propertyType.isValidValue(maxRawText)) {
+            throw new ConstraintValueDoNotMatchPropertyTypeException("Invalid max value for in range constraint ["
+                    + maxRawText + "] as it does not follow the property type [" + propertyType + "]");
+        }
+        min = ConstraintUtil.convertToComparable(propertyType, minRawText);
+        max = ConstraintUtil.convertToComparable(propertyType, maxRawText);
+    }
 
-	@Override
-	public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
-		// Perform verification that the property type is supported for
-		// comparison
-		ConstraintUtil.checkComparableType(propertyType);
-		if (inRange == null || inRange.size() != 2) {
-			throw new ConstraintValueDoNotMatchPropertyTypeException("In range constraint must have two elements.");
-		}
-		String minRawText = inRange.get(0);
-		String maxRawText = inRange.get(1);
-		if (!propertyType.isValidValue(minRawText)) {
-			throw new ConstraintValueDoNotMatchPropertyTypeException("Invalid min value for in range constraint ["
-					+ minRawText + "] as it does not follow the property type [" + propertyType + "]");
-		}
-		if (!propertyType.isValidValue(maxRawText)) {
-			throw new ConstraintValueDoNotMatchPropertyTypeException("Invalid max value for in range constraint ["
-					+ maxRawText + "] as it does not follow the property type [" + propertyType + "]");
-		}
-		min = ConstraintUtil.convertToComparable(propertyType, minRawText);
-		max = ConstraintUtil.convertToComparable(propertyType, maxRawText);
-	}
+    @Override
+    public void validate(Object propertyValue) throws ConstraintViolationException {
+        if (propertyValue == null) {
+            throw new ConstraintViolationException("Value to check is null");
+        }
+        if (!(min.getClass().isAssignableFrom(propertyValue.getClass()))) {
+            throw new ConstraintViolationException("Value to check is not comparable to range type, value type ["
+                    + propertyValue.getClass() + "], range type [" + min.getClass() + "]");
+        }
+        if (min.compareTo(propertyValue) > 0 || max.compareTo(propertyValue) < 0) {
+            throw new ConstraintViolationException("The value [" + propertyValue + "] is out of range " + inRange);
+        }
+    }
 
-	@Override
-	public void validate(Object propertyValue) throws ConstraintViolationException {
-		if (propertyValue == null) {
-			throw new ConstraintViolationException("Value to check is null");
-		}
-		if (!(min.getClass().isAssignableFrom(propertyValue.getClass()))) {
-			throw new ConstraintViolationException("Value to check is not comparable to range type, value type ["
-					+ propertyValue.getClass() + "], range type [" + min.getClass() + "]");
-		}
-		if (min.compareTo(propertyValue) > 0 || max.compareTo(propertyValue) < 0) {
-			throw new ConstraintViolationException("The value [" + propertyValue + "] is out of range " + inRange);
-		}
-	}
+    @NotNull
+    public String getRangeMinValue() {
+        if (inRange != null) {
+            return inRange.get(0);
+        } else {
+            return null;
+        }
+    }
 
-	// @JsonProperty
-	@NotNull
-	public String getRangeMinValue() {
-		if (inRange != null) {
-			return inRange.get(0);
-		} else {
-			return null;
-		}
-	}
+    public void setRangeMinValue(String minValue) {
+        if (inRange == null) {
+            inRange = Lists.newArrayList(minValue, "");
+        } else {
+            inRange.set(0, minValue);
+        }
+    }
 
-	// @JsonProperty
-	public void setRangeMinValue(String minValue) {
-		if (inRange == null) {
-			inRange = Lists.newArrayList(minValue, "");
-		} else {
-			inRange.set(0, minValue);
-		}
-	}
+    @NotNull
+    public String getRangeMaxValue() {
+        if (inRange != null) {
+            return inRange.get(1);
+        } else {
+            return null;
+        }
+    }
 
-	// @JsonProperty
-	@NotNull
-	public String getRangeMaxValue() {
-		if (inRange != null) {
-			return inRange.get(1);
-		} else {
-			return null;
-		}
-	}
-
-	// @JsonProperty
-	public void setRangeMaxValue(String maxValue) {
-		if (inRange == null) {
-			inRange = Lists.newArrayList("", maxValue);
-		} else {
-			inRange.set(1, maxValue);
-		}
-	}
+    public void setRangeMaxValue(String maxValue) {
+        if (inRange == null) {
+            inRange = Lists.newArrayList("", maxValue);
+        } else {
+            inRange.set(1, maxValue);
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java
index 2ba0071..c07ac7e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java
@@ -20,35 +20,28 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
+import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
 import javax.validation.constraints.NotNull;
 
-import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
+public class LengthConstraint extends AbstractStringPropertyConstraint {
 
-public class LengthConstraint extends AbstractStringPropertyConstraint implements Serializable {
+    @NotNull
+    private Integer length;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 6249912030281791233L;
+    @Override
+    protected void doValidate(String propertyValue) throws ConstraintViolationException {
+        if (propertyValue.length() != length) {
+            throw new ConstraintViolationException("The length of the value is not equals to [" + length + "]");
+        }
+    }
 
-	@NotNull
-	private Integer length;
+    public Integer getLength() {
+        return length;
+    }
 
-	@Override
-	protected void doValidate(String propertyValue) throws ConstraintViolationException {
-		if (propertyValue.length() != length) {
-			throw new ConstraintViolationException("The length of the value is not equals to [" + length + "]");
-		}
-	}
-
-	public Integer getLength() {
-		return length;
-	}
-
-	public void setLength(Integer length) {
-		this.length = length;
-	}
+    public void setLength(Integer length) {
+        this.length = length;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java
index 1491fe3..7d61dd3 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java
@@ -20,51 +20,39 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-
-import javax.validation.constraints.NotNull;
-
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
-//import alien4cloud.json.deserializer.TextDeserializer;
-//import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import javax.validation.constraints.NotNull;
 
-public class LessOrEqualConstraint extends AbstractComparablePropertyConstraint implements Serializable {
+public class LessOrEqualConstraint extends AbstractComparablePropertyConstraint {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -4907864317687138678L;
+    @NotNull
+    private String lessOrEqual;
 
-	// @JsonDeserialize(using = TextDeserializer.class)
-	@NotNull
-	private String lessOrEqual;
+    public LessOrEqualConstraint(String lessOrEqual) {
+        this.lessOrEqual = lessOrEqual;
+    }
 
-	public LessOrEqualConstraint(String lessOrEqual) {
-		super();
-		this.lessOrEqual = lessOrEqual;
-	}
+    @Override
+    public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
+        initialize(lessOrEqual, propertyType);
+    }
 
-	@Override
-	public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
-		initialize(lessOrEqual, propertyType);
-	}
+    @Override
+    protected void doValidate(Object propertyValue) throws ConstraintViolationException {
+        if (getComparable().compareTo(propertyValue) < 0) {
+            throw new ConstraintViolationException(propertyValue + " >= " + lessOrEqual);
+        }
+    }
 
-	@Override
-	protected void doValidate(Object propertyValue) throws ConstraintViolationException {
-		if (getComparable().compareTo(propertyValue) < 0) {
-			throw new ConstraintViolationException(propertyValue + " >= " + lessOrEqual);
-		}
-	}
+    public String getLessOrEqual() {
+        return lessOrEqual;
+    }
 
-	public String getLessOrEqual() {
-		return lessOrEqual;
-	}
-
-	public void setLessOrEqual(String lessOrEqual) {
-		this.lessOrEqual = lessOrEqual;
-	}
+    public void setLessOrEqual(String lessOrEqual) {
+        this.lessOrEqual = lessOrEqual;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java
index 2fc43fe..e2db77b 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java
@@ -20,39 +20,31 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-
-import javax.validation.constraints.NotNull;
-
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
-public class LessThanConstraint extends AbstractComparablePropertyConstraint implements Serializable {
+import javax.validation.constraints.NotNull;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 2267623014703859501L;
+public class LessThanConstraint extends AbstractComparablePropertyConstraint {
 
-	@NotNull
-	private String lessThan;
+    @NotNull
+    private String lessThan;
 
-	public LessThanConstraint(String lessThan) {
-		super();
-		this.lessThan = lessThan;
-	}
+    public LessThanConstraint(String lessThan) {
+        this.lessThan = lessThan;
+    }
 
-	@Override
-	public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
-		initialize(lessThan, propertyType);
-	}
+    @Override
+    public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
+        initialize(lessThan, propertyType);
+    }
 
-	@Override
-	protected void doValidate(Object propertyValue) throws ConstraintViolationException {
-		if (getComparable().compareTo(propertyValue) <= 0) {
-			throw new ConstraintViolationException(propertyValue + " > " + lessThan);
-		}
-	}
+    @Override
+    protected void doValidate(Object propertyValue) throws ConstraintViolationException {
+        if (getComparable().compareTo(propertyValue) <= 0) {
+            throw new ConstraintViolationException(propertyValue + " > " + lessThan);
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java
index b6a80af..8b7ce49 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java
@@ -20,42 +20,35 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
+import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
 import javax.validation.constraints.NotNull;
 
-import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
+public class MaxLengthConstraint extends AbstractStringPropertyConstraint {
 
-public class MaxLengthConstraint extends AbstractStringPropertyConstraint implements Serializable {
+    @NotNull
+    private Integer maxLength;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 6377603705670201256L;
+    public MaxLengthConstraint(Integer maxLength) {
+        this.maxLength = maxLength;
+    }
 
-	@NotNull
-	private Integer maxLength;
+    public MaxLengthConstraint() {
+        super();
+    }
 
-	public MaxLengthConstraint(Integer maxLength) {
-		this.maxLength = maxLength;
-	}
+    @Override
+    protected void doValidate(String propertyValue) throws ConstraintViolationException {
+        if (propertyValue.length() > maxLength) {
+            throw new ConstraintViolationException("The length of the value is greater than [" + maxLength + "]");
+        }
+    }
 
-	public MaxLengthConstraint() {
-		super();
-	}
+    public Integer getMaxLength() {
+        return maxLength;
+    }
 
-	@Override
-	protected void doValidate(String propertyValue) throws ConstraintViolationException {
-		if (propertyValue.length() > maxLength) {
-			throw new ConstraintViolationException("The length of the value is greater than [" + maxLength + "]");
-		}
-	}
-
-	public Integer getMaxLength() {
-		return maxLength;
-	}
-
-	public void setMaxLength(Integer maxLength) {
-		this.maxLength = maxLength;
-	}
+    public void setMaxLength(Integer maxLength) {
+        this.maxLength = maxLength;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java
index f92e5fb..bc51f4f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java
@@ -20,43 +20,36 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
+import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
 import javax.validation.constraints.NotNull;
 
-import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
+public class MinLengthConstraint extends AbstractStringPropertyConstraint {
 
-public class MinLengthConstraint extends AbstractStringPropertyConstraint implements Serializable {
+    @NotNull
+    private Integer minLength;
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 32422424680811240L;
+    public MinLengthConstraint(Integer minLength) {
+        this.minLength = minLength;
+    }
 
-	@NotNull
-	private Integer minLength;
+    public MinLengthConstraint() {
+        super();
+    }
 
-	public MinLengthConstraint(Integer minLength) {
-		this.minLength = minLength;
-	}
+    @Override
+    protected void doValidate(String propertyValue) throws ConstraintViolationException {
+        if (propertyValue.length() < minLength) {
+            throw new ConstraintViolationException("The length of the value is less than [" + minLength + "]");
+        }
+    }
 
-	public MinLengthConstraint() {
-		super();
-	}
+    public Integer getMinLength() {
+        return minLength;
+    }
 
-	@Override
-	protected void doValidate(String propertyValue) throws ConstraintViolationException {
-		if (propertyValue.length() < minLength) {
-			throw new ConstraintViolationException("The length of the value is less than [" + minLength + "]");
-		}
-	}
-
-	public Integer getMinLength() {
-		return minLength;
-	}
-
-	public void setMinLength(Integer minLength) {
-		this.minLength = minLength;
-	}
+    public void setMinLength(Integer minLength) {
+        this.minLength = minLength;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java
index c85c160..db26c33 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java
@@ -20,37 +20,27 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-import java.util.regex.Pattern;
-
-import javax.validation.constraints.NotNull;
-
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
-//import com.fasterxml.jackson.annotation.JsonIgnore;
+import javax.validation.constraints.NotNull;
+import java.util.regex.Pattern;
 
-public class PatternConstraint extends AbstractStringPropertyConstraint implements Serializable {
+public class PatternConstraint extends AbstractStringPropertyConstraint {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 8708185294968697107L;
+    @NotNull
+    private String pattern;
 
-	@NotNull
-	private String pattern;
+    private Pattern compiledPattern;
 
-	// @JsonIgnore
-	private Pattern compiledPattern;
+    public void setPattern(String pattern) {
+        this.pattern = pattern;
+        this.compiledPattern = Pattern.compile(this.pattern);
+    }
 
-	public void setPattern(String pattern) {
-		this.pattern = pattern;
-		this.compiledPattern = Pattern.compile(this.pattern);
-	}
-
-	@Override
-	protected void doValidate(String propertyValue) throws ConstraintViolationException {
-		if (!compiledPattern.matcher(propertyValue).matches()) {
-			throw new ConstraintViolationException("The value do not match pattern " + pattern);
-		}
-	}
+    @Override
+    protected void doValidate(String propertyValue) throws ConstraintViolationException {
+        if (!compiledPattern.matcher(propertyValue).matches()) {
+            throw new ConstraintViolationException("The value do not match pattern " + pattern);
+        }
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java
index 738f515..0b35a9b 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java
@@ -20,73 +20,61 @@
 
 package org.openecomp.sdc.be.model.tosca.constraints;
 
-import java.io.Serializable;
-import java.util.List;
-import java.util.Set;
-
-import javax.validation.constraints.NotNull;
-
+import com.google.common.collect.Sets;
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException;
 
-//import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.google.common.collect.Sets;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Set;
 
-public class ValidValuesConstraint extends AbstractPropertyConstraint implements Serializable {
+public class ValidValuesConstraint extends AbstractPropertyConstraint {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 5906087180079892853L;
+    @NotNull
+    private List<String> validValues;
+    private Set<Object> validValuesTyped;
 
-	@NotNull
-	private List<String> validValues;
-	// @JsonIgnore
-	private Set<Object> validValuesTyped;
+    public ValidValuesConstraint(List<String> validValues) {
+        this.validValues = validValues;
+    }
 
-	public ValidValuesConstraint(List<String> validValues) {
-		super();
-		this.validValues = validValues;
-	}
+    public ValidValuesConstraint() {
+    }
 
-	public ValidValuesConstraint() {
-		super();
-	}
+    @Override
+    public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
+        validValuesTyped = Sets.newHashSet();
+        if (validValues == null) {
+            throw new ConstraintValueDoNotMatchPropertyTypeException(
+                    "validValues constraint has invalid value <> property type is <" + propertyType.toString() + ">");
+        }
+        for (String value : validValues) {
+            if (!propertyType.isValidValue(value)) {
+                throw new ConstraintValueDoNotMatchPropertyTypeException("validValues constraint has invalid value <"
+                        + value + "> property type is <" + propertyType.toString() + ">");
+            } else {
+                validValuesTyped.add(propertyType.convert(value));
+            }
+        }
+    }
 
-	@Override
-	public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
-		validValuesTyped = Sets.newHashSet();
-		if (validValues == null) {
-			throw new ConstraintValueDoNotMatchPropertyTypeException(
-					"validValues constraint has invalid value <> property type is <" + propertyType.toString() + ">");
-		}
-		for (String value : validValues) {
-			if (!propertyType.isValidValue(value)) {
-				throw new ConstraintValueDoNotMatchPropertyTypeException("validValues constraint has invalid value <"
-						+ value + "> property type is <" + propertyType.toString() + ">");
-			} else {
-				validValuesTyped.add(propertyType.convert(value));
-			}
-		}
-	}
+    @Override
+    public void validate(Object propertyValue) throws ConstraintViolationException {
+        if (propertyValue == null) {
+            throw new ConstraintViolationException("Value to validate is null");
+        }
+        if (!validValuesTyped.contains(propertyValue)) {
+            throw new ConstraintViolationException("The value is not in the list of valid values");
+        }
+    }
 
-	@Override
-	public void validate(Object propertyValue) throws ConstraintViolationException {
-		if (propertyValue == null) {
-			throw new ConstraintViolationException("Value to validate is null");
-		}
-		if (!validValuesTyped.contains(propertyValue)) {
-			throw new ConstraintViolationException("The value is not in the list of valid values");
-		}
-	}
+    public List<String> getValidValues() {
+        return validValues;
+    }
 
-	public List<String> getValidValues() {
-		return validValues;
-	}
-
-	public void setValidValues(List<String> validValues) {
-		this.validValues = validValues;
-	}
+    public void setValidValues(List<String> validValues) {
+        this.validValues = validValues;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.java
index c4237e9..a29bb01 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.java
@@ -30,21 +30,19 @@
  */
 public class ConstraintFunctionalException extends FunctionalException {
 
-	private static final long serialVersionUID = 1L;
+    protected final transient ConstraintInformation constraintInformation;
 
-	protected ConstraintInformation constraintInformation;
+    public ConstraintFunctionalException(String message, Throwable cause) {
+        this(message, cause, null);
+    }
 
-	public ConstraintFunctionalException(String message, Throwable cause) {
-		super(message, cause);
-	}
+    public ConstraintFunctionalException(String message) {
+        this(message, null, null);
+    }
 
-	public ConstraintFunctionalException(String message) {
-		super(message);
-	}
-
-	public ConstraintFunctionalException(String message, Throwable cause, ConstraintInformation constraintInformation) {
-		super(message, cause);
-		this.constraintInformation = constraintInformation;
-	}
+    public ConstraintFunctionalException(String message, Throwable cause, ConstraintInformation constraintInformation) {
+        super(message, cause);
+        this.constraintInformation = constraintInformation;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.java
index 338e4aa..5c97a47 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.java
@@ -30,20 +30,16 @@
  */
 public class ConstraintRequiredParameterException extends ConstraintFunctionalException {
 
-	private static final long serialVersionUID = 1L;
+    public ConstraintRequiredParameterException(String message) {
+        super(message);
+    }
 
-	public ConstraintRequiredParameterException(String message) {
-		super(message);
-	}
+    public ConstraintRequiredParameterException(String message, Throwable cause) {
+        super(message, cause);
+    }
 
-	public ConstraintRequiredParameterException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-	public ConstraintRequiredParameterException(String message, Throwable cause,
-			ConstraintInformation constraintInformation) {
-		super(message, cause);
-		this.constraintInformation = constraintInformation;
-	}
+    public ConstraintRequiredParameterException(String message, Throwable cause, ConstraintInformation constraintInformation) {
+        super(message, cause, constraintInformation);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.java
index 3816ac6..f669e84 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.java
@@ -28,14 +28,11 @@
  */
 public class ConstraintTechnicalException extends Exception {
 
-	private static final long serialVersionUID = 5829360730980521567L;
+    public ConstraintTechnicalException(String message, Throwable cause) {
+        super(message, cause);
+    }
 
-	public ConstraintTechnicalException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-	public ConstraintTechnicalException(String message) {
-		super(message);
-	}
-
+    public ConstraintTechnicalException(String message) {
+        super(message);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.java
index 10d4e44..4adefb9 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.java
@@ -30,19 +30,15 @@
  */
 public class ConstraintValueDoNotMatchPropertyTypeException extends ConstraintFunctionalException {
 
-	private static final long serialVersionUID = 4342613849660957651L;
+    public ConstraintValueDoNotMatchPropertyTypeException(String message) {
+        super(message);
+    }
 
-	public ConstraintValueDoNotMatchPropertyTypeException(String message) {
-		super(message);
-	}
+    public ConstraintValueDoNotMatchPropertyTypeException(String message, Throwable cause) {
+        super(message, cause);
+    }
 
-	public ConstraintValueDoNotMatchPropertyTypeException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-	public ConstraintValueDoNotMatchPropertyTypeException(String message, Throwable cause,
-			ConstraintInformation constraintInformation) {
-		super(message, cause);
-		this.constraintInformation = constraintInformation;
-	}
+    public ConstraintValueDoNotMatchPropertyTypeException(String message, Throwable cause, ConstraintInformation constraintInformation) {
+        super(message, cause, constraintInformation);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.java
index 29db0aa..3101b7b 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.java
@@ -30,19 +30,16 @@
  */
 public class ConstraintViolationException extends ConstraintFunctionalException {
 
-	private static final long serialVersionUID = 1L;
+    public ConstraintViolationException(String message) {
+        super(message);
+    }
 
-	public ConstraintViolationException(String message) {
-		super(message);
-	}
+    public ConstraintViolationException(String message, Throwable cause) {
+        super(message, cause);
+    }
 
-	public ConstraintViolationException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-	public ConstraintViolationException(String message, Throwable cause, ConstraintInformation constraintInformation) {
-		super(message, cause);
-		this.constraintInformation = constraintInformation;
-	}
+    public ConstraintViolationException(String message, Throwable cause, ConstraintInformation constraintInformation) {
+        super(message, cause, constraintInformation);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.java
index 1454306..4ffc5f0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.java
@@ -29,13 +29,11 @@
  */
 public class FunctionalException extends Exception {
 
-	private static final long serialVersionUID = 6712845685798792493L;
+    public FunctionalException(String message, Throwable cause) {
+        super(message, cause);
+    }
 
-	public FunctionalException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-	public FunctionalException(String message) {
-		super(message);
-	}
+    public FunctionalException(String message) {
+        super(message);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.java
index 2b231d9..f4d920b 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.java
@@ -28,13 +28,11 @@
  */
 public class InvalidPropertyConstraintImplementationException extends ConstraintTechnicalException {
 
-	private static final long serialVersionUID = 2797550944328544706L;
+    public InvalidPropertyConstraintImplementationException(String message, Throwable cause) {
+        super(message, cause);
+    }
 
-	public InvalidPropertyConstraintImplementationException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-	public InvalidPropertyConstraintImplementationException(String message) {
-		super(message);
-	}
+    public InvalidPropertyConstraintImplementationException(String message) {
+        super(message);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.java
index 1bddeea..5d369a0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.java
@@ -28,13 +28,11 @@
  */
 public abstract class TechnicalException extends RuntimeException {
 
-	private static final long serialVersionUID = -9152473183025390161L;
+    public TechnicalException(String message, Throwable cause) {
+        super(message, cause);
+    }
 
-	public TechnicalException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-	public TechnicalException(String message) {
-		super(message);
-	}
+    public TechnicalException(String message) {
+        super(message);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.java
index f721efb..9ff4392 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.java
@@ -20,23 +20,23 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class BooleanConverter implements ToscaValueConverter {
-	private static BooleanConverter booleanConverter = new BooleanConverter();
+    private static BooleanConverter booleanConverter = new BooleanConverter();
 
-	public static BooleanConverter getInstance() {
-		return booleanConverter;
-	}
+    public static BooleanConverter getInstance() {
+        return booleanConverter;
+    }
 
-	private BooleanConverter() {
+    private BooleanConverter() {
 
-	}
+    }
 
-	@Override
-	public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		return Boolean.valueOf(value);
-	}
+    @Override
+    public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        return Boolean.valueOf(value);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverter.java
index 32929be..f3b842e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverter.java
@@ -1,19 +1,18 @@
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.io.StringReader;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.common.util.JsonUtils;
-
 import com.google.gson.Gson;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
 import com.google.gson.stream.JsonReader;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.common.util.JsonUtils;
+
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class DataTypePropertyConverter {
 
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.java
index c190298..11c0340 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.java
@@ -20,24 +20,24 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class DefaultConverter implements PropertyValueConverter {
 
-	private static DefaultConverter defaultConverter = new DefaultConverter();
+    private static DefaultConverter defaultConverter = new DefaultConverter();
 
-	public static DefaultConverter getInstance() {
-		return defaultConverter;
-	}
+    public static DefaultConverter getInstance() {
+        return defaultConverter;
+    }
 
-	private DefaultConverter() {
+    private DefaultConverter() {
 
-	}
+    }
 
-	@Override
-	public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		return value;
-	}
+    @Override
+    public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        return value;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.java
index d3edd9b..2d2ac72 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.java
@@ -20,23 +20,23 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class FloatConverter implements ToscaValueConverter {
-	private static FloatConverter floatConverter = new FloatConverter();
+    private static FloatConverter floatConverter = new FloatConverter();
 
-	public static FloatConverter getInstance() {
-		return floatConverter;
-	}
+    public static FloatConverter getInstance() {
+        return floatConverter;
+    }
 
-	private FloatConverter() {
+    private FloatConverter() {
 
-	}
+    }
 
-	@Override
-	public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		return Double.parseDouble(value);
-	}
+    @Override
+    public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        return Double.parseDouble(value);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.java
index 52fa9bf..77f4931 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.java
@@ -20,35 +20,35 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class HeatBooleanConverter implements PropertyValueConverter {
 
-	private static HeatBooleanConverter booleanConverter = new HeatBooleanConverter();
+    private static HeatBooleanConverter booleanConverter = new HeatBooleanConverter();
 
-	public static HeatBooleanConverter getInstance() {
-		return booleanConverter;
-	}
+    public static HeatBooleanConverter getInstance() {
+        return booleanConverter;
+    }
 
-	private HeatBooleanConverter() {
+    private HeatBooleanConverter() {
 
-	}
+    }
 
-	@Override
-	public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+    @Override
+    public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
 
-		if (value == null || value.isEmpty()) {
-			return null;
-		}
+        if (value == null || value.isEmpty()) {
+            return null;
+        }
 
-		if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("t") || value.equalsIgnoreCase("on")
-				|| value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("y") || value.equalsIgnoreCase("1")) {
-			return "true";
-		} else {
-			return "false";
-		}
-	}
+        if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("t") || value.equalsIgnoreCase("on")
+                || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("y") || value.equalsIgnoreCase("1")) {
+            return "true";
+        } else {
+            return "false";
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.java
index 30c21c8..04c2a7d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.java
@@ -20,33 +20,33 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.common.util.ValidationUtils;
 
+import java.util.Map;
+
 public class HeatCommaDelimitedListConverter implements PropertyValueConverter {
 
-	private static HeatCommaDelimitedListConverter stringConverter = new HeatCommaDelimitedListConverter();
+    private static HeatCommaDelimitedListConverter stringConverter = new HeatCommaDelimitedListConverter();
 
-	public static HeatCommaDelimitedListConverter getInstance() {
-		return stringConverter;
-	}
+    public static HeatCommaDelimitedListConverter getInstance() {
+        return stringConverter;
+    }
 
-	private HeatCommaDelimitedListConverter() {
+    private HeatCommaDelimitedListConverter() {
 
-	}
+    }
 
-	@Override
-	public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		String coverted = null;
-		if(original != null){
-			coverted = ValidationUtils.removeNoneUtf8Chars(original);
-			coverted = ValidationUtils.removeHtmlTagsOnly(coverted);
-			coverted = ValidationUtils.normaliseWhitespace(coverted);
-			coverted = ValidationUtils.stripOctets(coverted);
-		}
-		return coverted;
-	}
+    @Override
+    public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        String coverted = null;
+        if(original != null){
+            coverted = ValidationUtils.removeNoneUtf8Chars(original);
+            coverted = ValidationUtils.removeHtmlTagsOnly(coverted);
+            coverted = ValidationUtils.normaliseWhitespace(coverted);
+            coverted = ValidationUtils.stripOctets(coverted);
+        }
+        return coverted;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.java
index 9922c0f..90618ce 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.java
@@ -20,34 +20,34 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.common.util.ValidationUtils;
 
+import java.util.Map;
+
 public class HeatJsonConverter implements PropertyValueConverter {
 
-	private static HeatJsonConverter jsonConverter = new HeatJsonConverter();
+    private static HeatJsonConverter jsonConverter = new HeatJsonConverter();
 
-	public static HeatJsonConverter getInstance() {
-		return jsonConverter;
-	}
+    public static HeatJsonConverter getInstance() {
+        return jsonConverter;
+    }
 
-	private HeatJsonConverter() {
+    private HeatJsonConverter() {
 
-	}
+    }
 
-	@Override
-	public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		if (original == null) {
-			return null;
-		}
-		String converted = ValidationUtils.removeNoneUtf8Chars(original);
-		converted = ValidationUtils.removeHtmlTagsOnly(converted);
-		converted = ValidationUtils.normaliseWhitespace(converted);
-		converted = ValidationUtils.stripOctets(converted);
-		// As opposed to string converter, keeping the " and ' symbols
-		return converted;
-	}
+    @Override
+    public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        if (original == null) {
+            return null;
+        }
+        String converted = ValidationUtils.removeNoneUtf8Chars(original);
+        converted = ValidationUtils.removeHtmlTagsOnly(converted);
+        converted = ValidationUtils.normaliseWhitespace(converted);
+        converted = ValidationUtils.stripOctets(converted);
+        // As opposed to string converter, keeping the " and ' symbols
+        return converted;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.java
index 8798b54..187793e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.java
@@ -20,31 +20,31 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+
 import java.math.BigDecimal;
 import java.util.Map;
 
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
 public class HeatNumberConverter implements PropertyValueConverter {
 
-	private static HeatNumberConverter numberConverter = new HeatNumberConverter();
+    private static HeatNumberConverter numberConverter = new HeatNumberConverter();
 
-	public static HeatNumberConverter getInstance() {
-		return numberConverter;
-	}
+    public static HeatNumberConverter getInstance() {
+        return numberConverter;
+    }
 
-	private HeatNumberConverter() {
+    private HeatNumberConverter() {
 
-	}
+    }
 
-	@Override
-	public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+    @Override
+    public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) {
 
-		if (original == null || original.isEmpty()) {
-			return null;
-		}
+        if (original == null || original.isEmpty()) {
+            return null;
+        }
 
-		return new BigDecimal(original).toPlainString();
-	}
+        return new BigDecimal(original).toPlainString();
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.java
index 3f2b6ea..3bc379c 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.java
@@ -20,33 +20,33 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.common.util.ValidationUtils;
 
+import java.util.Map;
+
 public class HeatStringConverter implements PropertyValueConverter {
 
-	private static HeatStringConverter stringConverter = new HeatStringConverter();
+    private static HeatStringConverter stringConverter = new HeatStringConverter();
 
-	public static HeatStringConverter getInstance() {
-		return stringConverter;
-	}
+    public static HeatStringConverter getInstance() {
+        return stringConverter;
+    }
 
-	private HeatStringConverter() {
+    private HeatStringConverter() {
 
-	}
+    }
 
-	@Override
-	public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		String coverted = null;
-		if(original != null){
-			coverted = ValidationUtils.removeNoneUtf8Chars(original);
-			coverted = ValidationUtils.normaliseWhitespace(coverted);
-			coverted = ValidationUtils.stripOctets(coverted);
-			coverted = ValidationUtils.removeHtmlTagsOnly(coverted);
-		}
-		return coverted;
-	}
+    @Override
+    public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        String coverted = null;
+        if(original != null){
+            coverted = ValidationUtils.removeNoneUtf8Chars(original);
+            coverted = ValidationUtils.normaliseWhitespace(coverted);
+            coverted = ValidationUtils.stripOctets(coverted);
+            coverted = ValidationUtils.removeHtmlTagsOnly(coverted);
+        }
+        return coverted;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.java
index 30fbf69..f5e0a61 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.java
@@ -20,28 +20,28 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class IntegerConverter implements ToscaValueConverter {
 
-	private static IntegerConverter integerConverter = new IntegerConverter();
+    private static IntegerConverter integerConverter = new IntegerConverter();
 
-	public static IntegerConverter getInstance() {
-		return integerConverter;
-	}
+    public static IntegerConverter getInstance() {
+        return integerConverter;
+    }
 
-	private IntegerConverter() {
+    private IntegerConverter() {
 
-	}
+    }
 
-	@Override
-	public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		if ( value == null || value.isEmpty() ){
-			return null;
-		}
-		return Integer.parseInt(value);
-	}
+    @Override
+    public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        if ( value == null || value.isEmpty() ){
+            return null;
+        }
+        return Integer.parseInt(value);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java
index 3472b64..db2004a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java
@@ -20,42 +20,41 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.io.StringReader;
-import java.util.Map;
-
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.common.util.GsonFactory;
-
 import com.google.gson.Gson;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonParser;
 import com.google.gson.stream.JsonReader;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.common.util.GsonFactory;
+
+import java.io.StringReader;
+import java.util.Map;
 
 public class JsonConverter implements PropertyValueConverter {
 
-	private static JsonConverter jsonConverter = new JsonConverter();
+    private static JsonConverter jsonConverter = new JsonConverter();
 
-	private static JsonParser jsonParser = new JsonParser();
+    private static JsonParser jsonParser = new JsonParser();
 
-	private static Gson gson = GsonFactory.getGson();
+    private static Gson gson = GsonFactory.getGson();
 
-	public static JsonConverter getInstance() {
-		return jsonConverter;
-	}
+    public static JsonConverter getInstance() {
+        return jsonConverter;
+    }
 
-	private JsonConverter() {
+    private JsonConverter() {
 
-	}
+    }
 
-	@Override
-	public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		StringReader reader = new StringReader(value);
-		JsonReader jsonReader = new JsonReader(reader);
-		jsonReader.setLenient(true);
-		JsonElement jsonElement = jsonParser.parse(jsonReader);
-		if (jsonElement.isJsonPrimitive()) {
-			return value;
-		}
-		return gson.toJson(jsonElement);
-	}
+    @Override
+    public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        StringReader reader = new StringReader(value);
+        JsonReader jsonReader = new JsonReader(reader);
+        jsonReader.setLenient(true);
+        JsonElement jsonElement = jsonParser.parse(jsonReader);
+        if (jsonElement.isJsonPrimitive()) {
+            return value;
+        }
+        return gson.toJson(jsonElement);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java
index 4f6de9b..0078340 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java
@@ -20,200 +20,191 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
+import com.google.gson.*;
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
 import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
 import org.openecomp.sdc.be.model.tosca.validators.ListValidator;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.GsonFactory;
 import org.openecomp.sdc.common.util.JsonUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonParser;
-
-import fj.data.Either;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 
 public class ListConverter implements PropertyValueConverter {
 
-	private static ListConverter listConverter = new ListConverter();
-	private static Gson gson = GsonFactory.getGson();
-	private static Logger log = LoggerFactory.getLogger(ListValidator.class.getName());
+    private static ListConverter listConverter = new ListConverter();
+    private static Gson gson = GsonFactory.getGson();
+    private static final Logger log = Logger.getLogger(ListValidator.class.getName());
 
-	DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
+    DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
 
-	private static JsonParser jsonParser = new JsonParser();
+    private static JsonParser jsonParser = new JsonParser();
 
-	public static ListConverter getInstance() {
-		return listConverter;
-	}
+    public static ListConverter getInstance() {
+        return listConverter;
+    }
 
-	@Override
-	public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		Either<String, Boolean> convertWithErrorResult = this.convertWithErrorResult(value, innerType, dataTypes);
-		if (convertWithErrorResult.isRight()) {
-			return null;
-		}
+    @Override
+    public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        Either<String, Boolean> convertWithErrorResult = this.convertWithErrorResult(value, innerType, dataTypes);
+        if (convertWithErrorResult.isRight()) {
+            return null;
+        }
 
-		return convertWithErrorResult.left().value();
-	}
+        return convertWithErrorResult.left().value();
+    }
 
-	public Either<String, Boolean> convertWithErrorResult(String value, String innerType,
-			Map<String, DataTypeDefinition> dataTypes) {
-		if (value == null || innerType == null) {
-			return Either.left(value);
-		}
+    public Either<String, Boolean> convertWithErrorResult(String value, String innerType,
+            Map<String, DataTypeDefinition> dataTypes) {
+        if (value == null || innerType == null) {
+            return Either.left(value);
+        }
 
-		PropertyValueConverter innerConverter;
-		ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
+        PropertyValueConverter innerConverter;
+        ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
 
-		if (innerToscaType != null) {
-			PropertyValueConverter innerConverter1;
-			switch (innerToscaType) {
-			case STRING:
-				innerConverter1 = ToscaPropertyType.STRING.getConverter();
-				break;
-			case INTEGER:
-				innerConverter1 = ToscaPropertyType.INTEGER.getConverter();
-				break;
-			case FLOAT:
-				innerConverter1 = ToscaPropertyType.FLOAT.getConverter();
-				break;
-			case BOOLEAN:
-				innerConverter1 = ToscaPropertyType.BOOLEAN.getConverter();
-				break;
-			case JSON:
-				innerConverter1 = ToscaPropertyType.JSON.getConverter();
-				break;
-			default:
-				log.debug("inner Tosca Type is unknown");
-				return Either.left(value);
-			}
-			innerConverter = innerConverter1;
-		} else {
-			log.debug("inner Tosca Type {} ia a complex data type.", innerType);
+        if (innerToscaType != null) {
+            PropertyValueConverter innerConverter1;
+            switch (innerToscaType) {
+            case STRING:
+                innerConverter1 = ToscaPropertyType.STRING.getConverter();
+                break;
+            case INTEGER:
+                innerConverter1 = ToscaPropertyType.INTEGER.getConverter();
+                break;
+            case FLOAT:
+                innerConverter1 = ToscaPropertyType.FLOAT.getConverter();
+                break;
+            case BOOLEAN:
+                innerConverter1 = ToscaPropertyType.BOOLEAN.getConverter();
+                break;
+            case JSON:
+                innerConverter1 = ToscaPropertyType.JSON.getConverter();
+                break;
+            default:
+                log.debug("inner Tosca Type is unknown");
+                return Either.left(value);
+            }
+            innerConverter = innerConverter1;
+        } else {
+            log.debug("inner Tosca Type {} ia a complex data type.", innerType);
 
-			Either<String, Boolean> validateComplexInnerType = convertComplexInnerType(value, innerType, dataTypes);
+            return convertComplexInnerType(value, innerType, dataTypes);
+        }
 
-			return validateComplexInnerType;
-		}
+        try {
+            ArrayList<String> newList = new ArrayList<>();
 
-		try {
-			ArrayList<String> newList = new ArrayList<String>();
+            JsonArray jo = (JsonArray) jsonParser.parse(value);
+            if(ToscaPropertyType.JSON == innerToscaType)
+                return Either.left(value);
+            int size = jo.size();
+            for (int i = 0; i < size; i++) {
+                JsonElement currentValue = jo.get(i);
+                String element = JsonUtils.toString(currentValue);
 
-			JsonArray jo = (JsonArray) jsonParser.parse(value);
-			if(ToscaPropertyType.JSON == innerToscaType)
-				return Either.left(value);
-			int size = jo.size();
-			for (int i = 0; i < size; i++) {
-				JsonElement currentValue = jo.get(i);
-				String element = JsonUtils.toString(currentValue);
+                if (element == null || element.isEmpty()) {
+                    continue;
+                }
+                element = innerConverter.convert(element, null, dataTypes);
+                newList.add(element);
+            }
 
-				if (element == null || element.isEmpty()) {
-					continue;
-				}
-				element = innerConverter.convert(element, null, dataTypes);
-				newList.add(element);
-			}
+            switch (innerToscaType) {
+            case STRING:
+                value = gson.toJson(newList);
+                break;
+            case INTEGER:
+                List<BigInteger> intList = new ArrayList<>();
 
-			switch (innerToscaType) {
-			case STRING:
-				value = gson.toJson(newList);
-				break;
-			case INTEGER:
-				List<BigInteger> intList = new ArrayList<BigInteger>();
+                for (String str : newList) {
+                    int base = 10;
+                    if (str.contains("0x")) {
+                        str = str.replaceFirst("0x", "");
+                        base = 16;
+                    }
+                    if (str.contains("0o")) {
+                        str = str.replaceFirst("0o", "");
+                        base = 8;
+                    }
+                    intList.add(new BigInteger(str, base));
+                }
+                value = gson.toJson(intList);
+                break;
+            case FLOAT:
+                value = "[";
+                for (String str : newList) {
+                    value += str + ",";
+                }
+                value = value.substring(0, value.length() - 1);
+                value += "]";
+                break;
+            case BOOLEAN:
+                List<Boolean> boolList = new ArrayList<>();
+                for (String str : newList) {
+                    boolList.add(Boolean.valueOf(str));
+                }
+                value = gson.toJson(boolList);
+                break;
+            default:
+                value = gson.toJson(newList);
+                log.debug("inner Tosca Type unknown : {}", innerToscaType);
+            }
 
-				for (String str : newList) {
-					int base = 10;
-					if (str.contains("0x")) {
-						str = str.replaceFirst("0x", "");
-						base = 16;
-					}
-					if (str.contains("0o")) {
-						str = str.replaceFirst("0o", "");
-						base = 8;
-					}
-					intList.add(new BigInteger(str, base));
-				}
-				value = gson.toJson(intList);
-				break;
-			case FLOAT:
-				value = "[";
-				for (String str : newList) {
-					value += str + ",";
-				}
-				value = value.substring(0, value.length() - 1);
-				value += "]";
-				break;
-			case BOOLEAN:
-				List<Boolean> boolList = new ArrayList<Boolean>();
-				for (String str : newList) {
-					boolList.add(Boolean.valueOf(str));
-				}
-				value = gson.toJson(boolList);
-				break;
-			default:
-				value = gson.toJson(newList);
-				log.debug("inner Tosca Type unknown : {}", innerToscaType);
-			}
+        } catch (JsonParseException e) {
+            log.debug("Failed to parse json : {}", value, e);
+            BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter");
+            return Either.right(false);
+        }
 
-		} catch (JsonParseException e) {
-			log.debug("Failed to parse json : {}", value, e);
-			BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter");
-			return Either.right(false);
-		}
+        return Either.left(value);
+    }
 
-		return Either.left(value);
-	}
+    private Either<String, Boolean> convertComplexInnerType(String value, String innerType,
+            Map<String, DataTypeDefinition> allDataTypes) {
 
-	private Either<String, Boolean> convertComplexInnerType(String value, String innerType,
-			Map<String, DataTypeDefinition> allDataTypes) {
+        DataTypeDefinition dataTypeDefinition = allDataTypes.get(innerType);
+        if (dataTypeDefinition == null) {
+            log.debug("Cannot find data type {}", innerType);
+            return Either.right(false);
+        }
 
-		DataTypeDefinition dataTypeDefinition = allDataTypes.get(innerType);
-		if (dataTypeDefinition == null) {
-			log.debug("Cannot find data type {}", innerType);
-			return Either.right(false);
-		}
+        List<JsonElement> newList = new ArrayList<>();
 
-		List<JsonElement> newList = new ArrayList<>();
+        try {
 
-		try {
+            JsonArray jo = (JsonArray) jsonParser.parse(value);
+            int size = jo.size();
+            for (int i = 0; i < size; i++) {
+                JsonElement currentValue = jo.get(i);
 
-			JsonArray jo = (JsonArray) jsonParser.parse(value);
-			int size = jo.size();
-			for (int i = 0; i < size; i++) {
-				JsonElement currentValue = jo.get(i);
+                if (currentValue != null) {
 
-				if (currentValue != null) {
+                    String element = JsonUtils.toString(currentValue);
 
-					String element = JsonUtils.toString(currentValue);
-
-					ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter
-							.validateAndUpdate(element, dataTypeDefinition, allDataTypes);
-					if (validateAndUpdate.right.booleanValue() == false) {
-						log.debug("Cannot parse value {} from type {} in list position {}",currentValue,innerType,i);
-						return Either.right(false);
-					}
-					JsonElement newValue = validateAndUpdate.left;
-					newList.add(newValue);
-				}
-			}
-		} catch (Exception e) {
-			log.debug("Failed to parse the value {} of list parameter.", value);
-			return Either.right(false);
-		}
-		value = gson.toJson(newList);
-		return Either.left(value);
-	}
+                    ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter
+                            .validateAndUpdate(element, dataTypeDefinition, allDataTypes);
+                    if (!validateAndUpdate.right.booleanValue()) {
+                        log.debug("Cannot parse value {} from type {} in list position {}",currentValue,innerType,i);
+                        return Either.right(false);
+                    }
+                    JsonElement newValue = validateAndUpdate.left;
+                    newList.add(newValue);
+                }
+            }
+        } catch (Exception e) {
+            log.debug("Failed to parse the value {} of list parameter.", value);
+            return Either.right(false);
+        }
+        value = gson.toJson(newList);
+        return Either.left(value);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.java
index f33be29..6e799da 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.java
@@ -20,29 +20,29 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class LowerCaseConverter implements PropertyValueConverter {
 
-	private static LowerCaseConverter booleanConverter = new LowerCaseConverter();
+    private static LowerCaseConverter booleanConverter = new LowerCaseConverter();
 
-	public static LowerCaseConverter getInstance() {
-		return booleanConverter;
-	}
+    public static LowerCaseConverter getInstance() {
+        return booleanConverter;
+    }
 
-	private LowerCaseConverter() {
+    private LowerCaseConverter() {
 
-	}
+    }
 
-	@Override
-	public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+    @Override
+    public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
 
-		if (value == null) {
-			return null;
-		}
-		return value.toLowerCase();
-	}
+        if (value == null) {
+            return null;
+        }
+        return value.toLowerCase();
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java
index 30b895f..f53d95c 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java
@@ -20,230 +20,221 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
+import com.google.gson.*;
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
 import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
 import org.openecomp.sdc.be.model.tosca.validators.ListValidator;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.GsonFactory;
 import org.openecomp.sdc.common.util.JsonUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonParser;
-
-import fj.data.Either;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
 
 public class MapConverter implements PropertyValueConverter {
 
-	private static MapConverter mapConverter = new MapConverter();
-	private static Gson gson = GsonFactory.getGson();
-	private static Logger log = LoggerFactory.getLogger(ListValidator.class.getName());
+    private static MapConverter mapConverter = new MapConverter();
+    private static Gson gson = GsonFactory.getGson();
+    private static final Logger log = Logger.getLogger(ListValidator.class.getName());
 
-	DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
+    DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
 
-	private static JsonParser jsonParser = new JsonParser();
+    private static JsonParser jsonParser = new JsonParser();
 
-	public static MapConverter getInstance() {
-		return mapConverter;
-	}
+    public static MapConverter getInstance() {
+        return mapConverter;
+    }
 
-	public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+    public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
 
-		Either<String, Boolean> convertWithErrorResult = this.convertWithErrorResult(value, innerType, dataTypes);
-		if (convertWithErrorResult.isRight()) {
-			return null;
-		}
+        Either<String, Boolean> convertWithErrorResult = this.convertWithErrorResult(value, innerType, dataTypes);
+        if (convertWithErrorResult.isRight()) {
+            return null;
+        }
 
-		return convertWithErrorResult.left().value();
-	}
+        return convertWithErrorResult.left().value();
+    }
 
-	public Either<String, Boolean> convertWithErrorResult(String value, String innerType,
-			Map<String, DataTypeDefinition> dataTypes) {
+    public Either<String, Boolean> convertWithErrorResult(String value, String innerType,
+            Map<String, DataTypeDefinition> dataTypes) {
 
-		if (value == null || value == "" || innerType == null) {
-			return Either.left(value);
-		}
+        if (value == null || value == "" || innerType == null) {
+            return Either.left(value);
+        }
 
-		PropertyValueConverter innerConverter;
-		PropertyValueConverter keyConverter = ToscaPropertyType.STRING.getConverter();
-		ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
+        PropertyValueConverter innerConverter;
+        PropertyValueConverter keyConverter = ToscaPropertyType.STRING.getConverter();
+        ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
 
-		if (innerToscaType != null) {
-			switch (innerToscaType) {
-			case STRING:
-				innerConverter = ToscaPropertyType.STRING.getConverter();
-				break;
-			case INTEGER:
-				innerConverter = ToscaPropertyType.INTEGER.getConverter();
-				break;
-			case FLOAT:
-				innerConverter = ToscaPropertyType.FLOAT.getConverter();
-				break;
-			case BOOLEAN:
-				innerConverter = ToscaPropertyType.BOOLEAN.getConverter();
-				break;
-			case JSON:
-				innerConverter = ToscaPropertyType.JSON.getConverter();
-				break;
-			default:
-				log.debug("inner Tosca Type is unknown");
-				return Either.left(value);
-			}
+        if (innerToscaType != null) {
+            switch (innerToscaType) {
+            case STRING:
+                innerConverter = ToscaPropertyType.STRING.getConverter();
+                break;
+            case INTEGER:
+                innerConverter = ToscaPropertyType.INTEGER.getConverter();
+                break;
+            case FLOAT:
+                innerConverter = ToscaPropertyType.FLOAT.getConverter();
+                break;
+            case BOOLEAN:
+                innerConverter = ToscaPropertyType.BOOLEAN.getConverter();
+                break;
+            case JSON:
+                innerConverter = ToscaPropertyType.JSON.getConverter();
+                break;
+            default:
+                log.debug("inner Tosca Type is unknown");
+                return Either.left(value);
+            }
 
-		} else {
+        } else {
 
-			log.debug("inner Tosca Type {} ia a complex data type.", innerType);
+            log.debug("inner Tosca Type {} ia a complex data type.", innerType);
 
-			Either<String, Boolean> validateComplexInnerType = convertComplexInnerType(value, innerType, keyConverter,
-					dataTypes);
+            return convertComplexInnerType(value, innerType, keyConverter,
+                    dataTypes);
 
-			return validateComplexInnerType;
+        }
 
-		}
+        try {
+            Map<String, String> newMap = new HashMap<>();
 
-		try {
-			Map<String, String> newMap = new HashMap<String, String>();
+            JsonElement jsonObject = jsonParser.parse(value);
+            JsonObject asJsonObject = jsonObject.getAsJsonObject();
+            Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
+            for (Entry<String, JsonElement> entry : entrySet) {
+                String key = entry.getKey();
+                JsonElement jsonValue = entry.getValue();
 
-			JsonElement jsonObject = jsonParser.parse(value);
-			JsonObject asJsonObject = jsonObject.getAsJsonObject();
-			Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
-			for (Entry<String, JsonElement> entry : entrySet) {
-				String key = entry.getKey();
-				JsonElement jsonValue = entry.getValue();
+                key = keyConverter.convert(entry.getKey(), null, dataTypes);
 
-				key = keyConverter.convert(entry.getKey(), null, dataTypes);
+                String element = JsonUtils.toString(jsonValue);
 
-				String element = JsonUtils.toString(jsonValue);
+                String val = innerConverter.convert(element, null, dataTypes);
+                newMap.put(key, val);
+            }
 
-				String val = innerConverter.convert(element, null, dataTypes);
-				newMap.put(key, val);
-			}
+            String objVal;
+            switch (innerToscaType) {
+            case STRING:
+                value = gson.toJson(newMap);
+                break;
+            case INTEGER:
+                String key = null;
+                Map<String, Integer> intMap = new HashMap<>();
+                for (Map.Entry<String, String> entry : newMap.entrySet()) {
+                    objVal = entry.getValue();
+                    key = entry.getKey();
+                    if (objVal != null) {
+                        intMap.put(key, Integer.valueOf(objVal.toString()));
+                    } else {
+                        intMap.put(key, null);
+                    }
 
-			String objVal;
-			switch (innerToscaType) {
-			case STRING:
-				value = gson.toJson(newMap);
-				break;
-			case INTEGER:
-				String key = null;
-				Map<String, Integer> intMap = new HashMap<String, Integer>();
-				for (Map.Entry<String, String> entry : newMap.entrySet()) {
-					objVal = entry.getValue();
-					key = entry.getKey();
-					if (objVal != null) {
-						intMap.put(key, Integer.valueOf(objVal.toString()));
-					} else {
-						intMap.put(key, null);
-					}
+                }
+                value = gson.toJson(intMap);
+                break;
+            case FLOAT:
+                value = "{";
+                for (Map.Entry<String, String> entry : newMap.entrySet()) {
+                    objVal = entry.getValue();
+                    if (objVal == null) {
+                        objVal = "null";
+                    }
+                    key = entry.getKey();
+                    value += "\"" + key + "\":" + objVal.toString() + ",";
+                }
+                value = value.substring(0, value.length() - 1);
+                value += "}";
+                break;
+            case BOOLEAN:
+                Map<String, Boolean> boolMap = new HashMap<>();
+                for (Map.Entry<String, String> entry : newMap.entrySet()) {
+                    objVal = entry.getValue();
+                    key = entry.getKey();
+                    if (objVal != null) {
+                        boolMap.put(key, Boolean.valueOf(objVal.toString()));
+                    } else {
+                        boolMap.put(key, null);
+                    }
+                }
+                value = gson.toJson(boolMap);
+                break;
+            default:
+                value = gson.toJson(newMap);
+                log.debug("inner Tosca Type unknown : {}", innerToscaType);
+            }
+        } catch (JsonParseException e) {
+            log.debug("Failed to parse json : {}", value, e);
+            BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Map Converter");
+            return Either.right(false);
+        }
 
-				}
-				value = gson.toJson(intMap);
-				break;
-			case FLOAT:
-				value = "{";
-				for (Map.Entry<String, String> entry : newMap.entrySet()) {
-					objVal = entry.getValue();
-					if (objVal == null) {
-						objVal = "null";
-					}
-					key = entry.getKey();
-					value += "\"" + key + "\":" + objVal.toString() + ",";
-				}
-				value = value.substring(0, value.length() - 1);
-				value += "}";
-				break;
-			case BOOLEAN:
-				Map<String, Boolean> boolMap = new HashMap<String, Boolean>();
-				for (Map.Entry<String, String> entry : newMap.entrySet()) {
-					objVal = entry.getValue();
-					key = entry.getKey();
-					if (objVal != null) {
-						boolMap.put(key, Boolean.valueOf(objVal.toString()));
-					} else {
-						boolMap.put(key, null);
-					}
-				}
-				value = gson.toJson(boolMap);
-				break;
-			default:
-				value = gson.toJson(newMap);
-				log.debug("inner Tosca Type unknown : {}", innerToscaType);
-			}
-		} catch (JsonParseException e) {
-			log.debug("Failed to parse json : {}", value, e);
-			BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Map Converter");
-			return Either.right(false);
-		}
+        return Either.left(value);
 
-		return Either.left(value);
+    }
 
-	}
+    /**
+     * convert the json value of map when the inner type is a complex data type
+     *
+     * @param value
+     * @param innerType
+     * @param keyConverter
+     * @param allDataTypes
+     * @return
+     */
+    private Either<String, Boolean> convertComplexInnerType(String value, String innerType,
+            PropertyValueConverter keyConverter, Map<String, DataTypeDefinition> allDataTypes) {
 
-	/**
-	 * convert the json value of map when the inner type is a complex data type
-	 * 
-	 * @param value
-	 * @param innerType
-	 * @param keyConverter
-	 * @param allDataTypes
-	 * @return
-	 */
-	private Either<String, Boolean> convertComplexInnerType(String value, String innerType,
-			PropertyValueConverter keyConverter, Map<String, DataTypeDefinition> allDataTypes) {
+        DataTypeDefinition dataTypeDefinition = allDataTypes.get(innerType);
+        if (dataTypeDefinition == null) {
+            log.debug("Cannot find data type {}", innerType);
+            return Either.right(false);
+        }
 
-		DataTypeDefinition dataTypeDefinition = allDataTypes.get(innerType);
-		if (dataTypeDefinition == null) {
-			log.debug("Cannot find data type {}", innerType);
-			return Either.right(false);
-		}
+        Map<String, JsonElement> newMap = new HashMap<>();
 
-		Map<String, JsonElement> newMap = new HashMap<String, JsonElement>();
+        try {
 
-		try {
+            JsonElement jsonObject = jsonParser.parse(value);
+            JsonObject asJsonObject = jsonObject.getAsJsonObject();
+            Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
+            for (Entry<String, JsonElement> entry : entrySet) {
+                String currentKey = keyConverter.convert(entry.getKey(), null, allDataTypes);
 
-			JsonElement jsonObject = jsonParser.parse(value);
-			JsonObject asJsonObject = jsonObject.getAsJsonObject();
-			Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
-			for (Entry<String, JsonElement> entry : entrySet) {
-				String currentKey = keyConverter.convert(entry.getKey(), null, allDataTypes);
+                JsonElement currentValue = entry.getValue();
 
-				JsonElement currentValue = entry.getValue();
+                if (currentValue != null) {
 
-				if (currentValue != null) {
+                    String element = JsonUtils.toString(currentValue);
 
-					String element = JsonUtils.toString(currentValue);
+                    ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter
+                            .validateAndUpdate(element, dataTypeDefinition, allDataTypes);
+                    if (!validateAndUpdate.right.booleanValue()) {
+                        log.debug("Cannot parse value {} from type {} of key {}",currentValue,innerType,currentKey);
+                        return Either.right(false);
+                    }
+                    JsonElement newValue = validateAndUpdate.left;
+                    newMap.put(currentKey, newValue);
+                } else {
+                    newMap.put(currentKey, null);
+                }
+            }
 
-					ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter
-							.validateAndUpdate(element, dataTypeDefinition, allDataTypes);
-					if (validateAndUpdate.right.booleanValue() == false) {
-						log.debug("Cannot parse value {} from type {} of key {}",currentValue,innerType,currentKey);
-						return Either.right(false);
-					}
-					JsonElement newValue = validateAndUpdate.left;
-					newMap.put(currentKey, newValue);
-				} else {
-					newMap.put(currentKey, null);
-				}
-			}
+        } catch (Exception e) {
+            log.debug("Cannot parse value {} of map from inner type {}", value, innerType);
+            return Either.right(false);
+        }
 
-		} catch (Exception e) {
-			log.debug("Cannot parse value {} of map from inner type {}", value, innerType);
-			return Either.right(false);
-		}
-
-		value = gson.toJson(newMap);
-		return Either.left(value);
-	}
+        value = gson.toJson(newMap);
+        return Either.left(value);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.java
index 254785f..b60b0a5 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.java
@@ -20,12 +20,12 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public interface PropertyValueConverter {
 
-	String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes);
+    String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.java
index f5a7ff6..ae53407 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.java
@@ -20,36 +20,36 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.common.util.ValidationUtils;
 
+import java.util.Map;
+
 public class StringConvertor implements PropertyValueConverter {
 
-	private static StringConvertor stringConverter = new StringConvertor();
+    private static StringConvertor stringConverter = new StringConvertor();
 
-	public static StringConvertor getInstance() {
-		return stringConverter;
-	}
+    public static StringConvertor getInstance() {
+        return stringConverter;
+    }
 
-	private StringConvertor() {
+    private StringConvertor() {
 
-	}
+    }
 
-	@Override
-	public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		if (original == null) {
-			return null;
-		}
-		String coverted = ValidationUtils.removeNoneUtf8Chars(original);
+    @Override
+    public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        if (original == null) {
+            return null;
+        }
+        String coverted = ValidationUtils.removeNoneUtf8Chars(original);
 
-		// coverted = ValidationUtils.convertHtmlTagsToEntities(coverted);
-		coverted = ValidationUtils.normaliseWhitespace(coverted);
-		coverted = ValidationUtils.stripOctets(coverted);
-		coverted = ValidationUtils.removeHtmlTagsOnly(coverted);
+        // coverted = ValidationUtils.convertHtmlTagsToEntities(coverted);
+        coverted = ValidationUtils.normaliseWhitespace(coverted);
+        coverted = ValidationUtils.stripOctets(coverted);
+        coverted = ValidationUtils.removeHtmlTagsOnly(coverted);
 
-		return coverted;
-	}
+        return coverted;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.java
index 977415b..346f637 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.java
@@ -20,35 +20,35 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class ToscaBooleanConverter implements PropertyValueConverter {
 
-	private static ToscaBooleanConverter booleanConverter = new ToscaBooleanConverter();
+    private static ToscaBooleanConverter booleanConverter = new ToscaBooleanConverter();
 
-	public static ToscaBooleanConverter getInstance() {
-		return booleanConverter;
-	}
+    public static ToscaBooleanConverter getInstance() {
+        return booleanConverter;
+    }
 
-	private ToscaBooleanConverter() {
+    private ToscaBooleanConverter() {
 
-	}
+    }
 
-	@Override
-	public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+    @Override
+    public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
 
-		if (value == null) {
-			return null;
-		}
+        if (value == null) {
+            return null;
+        }
 
-		if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("yes")
-				|| value.equalsIgnoreCase("y")) {
-			return "true";
-		} else {
-			return "false";
-		}
-	}
+        if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("yes")
+                || value.equalsIgnoreCase("y")) {
+            return "true";
+        } else {
+            return "false";
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaConverterUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaConverterUtils.java
index 4aadaa0..941535a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaConverterUtils.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaConverterUtils.java
@@ -1,8 +1,7 @@
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
-
 import com.google.gson.JsonObject;
+import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
 
 public class ToscaConverterUtils {
 
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.java
index ba765c9..417beea 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.java
@@ -20,12 +20,12 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.math.BigDecimal;
-import java.util.Map;
-
 import org.apache.commons.lang.StringUtils;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.math.BigDecimal;
+import java.util.Map;
+
 public class ToscaFloatConverter implements PropertyValueConverter {
 
     private static ToscaFloatConverter numberConverter = new ToscaFloatConverter();
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.java
index d70088e..0ce446d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.java
@@ -20,37 +20,36 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.io.StringReader;
-import java.util.Map;
-
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
 import com.google.gson.JsonElement;
 import com.google.gson.JsonParser;
 import com.google.gson.stream.JsonReader;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+
+import java.io.StringReader;
+import java.util.Map;
 
 public class ToscaJsonValueConverter extends ToscaValueBaseConverter implements ToscaValueConverter {
-	private static ToscaJsonValueConverter toscaJsonConverter = new ToscaJsonValueConverter();
+    private static ToscaJsonValueConverter toscaJsonConverter = new ToscaJsonValueConverter();
 
-	public static ToscaJsonValueConverter getInstance() {
-		return toscaJsonConverter;
-	}
+    public static ToscaJsonValueConverter getInstance() {
+        return toscaJsonConverter;
+    }
 
-	private ToscaJsonValueConverter() {
+    private ToscaJsonValueConverter() {
 
-	}
+    }
 
-	JsonParser jsonParser = new JsonParser();
+    JsonParser jsonParser = new JsonParser();
 
-	@Override
-	public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		StringReader reader = new StringReader(value);
-		JsonReader jsonReader = new JsonReader(reader);
-		jsonReader.setLenient(true);
-		JsonElement jsonElement = jsonParser.parse(jsonReader);
-		if (jsonElement.isJsonPrimitive()) {
-			return value;
-		}
-		return handleComplexJsonValue(jsonElement);
-	}
+    @Override
+    public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        StringReader reader = new StringReader(value);
+        JsonReader jsonReader = new JsonReader(reader);
+        jsonReader.setLenient(true);
+        JsonElement jsonElement = jsonParser.parse(jsonReader);
+        if (jsonElement.isJsonPrimitive()) {
+            return value;
+        }
+        return handleComplexJsonValue(jsonElement);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.java
index f3189ee..8eb4c10 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.java
@@ -20,6 +20,14 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
+import com.google.gson.*;
+import com.google.gson.stream.JsonReader;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -27,151 +35,136 @@
 import java.util.Map.Entry;
 import java.util.Set;
 
-import org.openecomp.sdc.be.config.BeEcompErrorManager;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonSyntaxException;
-import com.google.gson.stream.JsonReader;
-
 public class ToscaListValueConverter extends ToscaValueBaseConverter implements ToscaValueConverter {
-	private static ToscaListValueConverter listConverter = new ToscaListValueConverter();
-	private JsonParser jsonParser = new JsonParser();
-	private static Logger log = LoggerFactory.getLogger(ToscaListValueConverter.class.getName());
+    private static ToscaListValueConverter listConverter = new ToscaListValueConverter();
+    private JsonParser jsonParser = new JsonParser();
+    private static final Logger log = Logger.getLogger(ToscaListValueConverter.class.getName());
 
-	public static ToscaListValueConverter getInstance() {
-		return listConverter;
-	}
+    public static ToscaListValueConverter getInstance() {
+        return listConverter;
+    }
 
-	private ToscaListValueConverter() {
+    private ToscaListValueConverter() {
 
-	}
+    }
 
-	@Override
-	public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		if (value == null) {
-			return null;
-		}
-		try {
-			ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
-			ToscaValueConverter innerConverter = null;
-			boolean isScalar = true;
-			if (innerToscaType != null) {
-				innerConverter = innerToscaType.getValueConverter();
-			} else {
-				DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
+    @Override
+    public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        if (value == null) {
+            return null;
+        }
+        try {
+            ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
+            ToscaValueConverter innerConverter = null;
+            boolean isScalar = true;
+            if (innerToscaType != null) {
+                innerConverter = innerToscaType.getValueConverter();
+            } else {
+                DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
 
-				if (dataTypeDefinition != null) {
-					ToscaPropertyType toscaPropertyType = null;
-					if ((toscaPropertyType = isScalarType(dataTypeDefinition)) != null) {
-						innerConverter = toscaPropertyType.getValueConverter();
-					} else {
-						isScalar = false;
-						innerConverter = ToscaMapValueConverter.getInstance();
-					}
-				} else {
-					log.debug("inner Tosca Type is null");
-					return value;
-				}
-			}
-			JsonElement jsonElement = null;
-			try {
-				StringReader reader = new StringReader(value);
-				JsonReader jsonReader = new JsonReader(reader);
-				jsonReader.setLenient(true);
+                if (dataTypeDefinition != null) {
+                    ToscaPropertyType toscaPropertyType = null;
+                    if ((toscaPropertyType = isScalarType(dataTypeDefinition)) != null) {
+                        innerConverter = toscaPropertyType.getValueConverter();
+                    } else {
+                        isScalar = false;
+                        innerConverter = ToscaMapValueConverter.getInstance();
+                    }
+                } else {
+                    log.debug("inner Tosca Type is null");
+                    return value;
+                }
+            }
+            JsonElement jsonElement = null;
+            try {
+                StringReader reader = new StringReader(value);
+                JsonReader jsonReader = new JsonReader(reader);
+                jsonReader.setLenient(true);
 
-				jsonElement = jsonParser.parse(jsonReader);
-			} catch (JsonSyntaxException e) {
-				log.debug("convertToToscaValue failed to parse json value :", e);
-				return null;
-			}
-			if (jsonElement == null || true == jsonElement.isJsonNull()) {
-				log.debug("convertToToscaValue json element is null");
-				return null;
-			}
-			if (jsonElement.isJsonArray() == false) {
-				// get_input all array like get_input: qrouter_names
-				return handleComplexJsonValue(jsonElement);
-			}
-			JsonArray asJsonArray = jsonElement.getAsJsonArray();
+                jsonElement = jsonParser.parse(jsonReader);
+            } catch (JsonSyntaxException e) {
+                log.debug("convertToToscaValue failed to parse json value :", e);
+                return null;
+            }
+            if (jsonElement == null || jsonElement.isJsonNull()) {
+                log.debug("convertToToscaValue json element is null");
+                return null;
+            }
+            if (!jsonElement.isJsonArray()) {
+                // get_input all array like get_input: qrouter_names
+                return handleComplexJsonValue(jsonElement);
+            }
+            JsonArray asJsonArray = jsonElement.getAsJsonArray();
 
-			ArrayList<Object> toscaList = new ArrayList<Object>();
-			final boolean isScalarF = isScalar;
-			final ToscaValueConverter innerConverterFinal = innerConverter;
-			asJsonArray.forEach(e -> {
-				Object convertedValue = null;
-				if (isScalarF) {
-					if (e.isJsonPrimitive()) {
-						String jsonAsString = e.getAsString();
-						log.debug("try to convert scalar value {}", jsonAsString);
-						convertedValue = innerConverterFinal.convertToToscaValue(jsonAsString, innerType,
-								dataTypes);
-					} else {
-						convertedValue = handleComplexJsonValue(e);
-					}
+            ArrayList<Object> toscaList = new ArrayList<>();
+            final boolean isScalarF = isScalar;
+            final ToscaValueConverter innerConverterFinal = innerConverter;
+            asJsonArray.forEach(e -> {
+                Object convertedValue = null;
+                if (isScalarF) {
+                    if (e.isJsonPrimitive()) {
+                        String jsonAsString = e.getAsString();
+                        log.debug("try to convert scalar value {}", jsonAsString);
+                        convertedValue = innerConverterFinal.convertToToscaValue(jsonAsString, innerType,
+                                dataTypes);
+                    } else {
+                        convertedValue = handleComplexJsonValue(e);
+                    }
 
-				} else {
-					JsonObject asJsonObject = e.getAsJsonObject();
-					Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
+                } else {
+                    JsonObject asJsonObject = e.getAsJsonObject();
+                    Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
 
-					DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
-					Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
-					Map<String, Object> toscaObjectPresentation = new HashMap<>();
-					
-					for (Entry<String, JsonElement> entry : entrySet) {
-						String propName = entry.getKey();
+                    DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
+                    Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
+                    Map<String, Object> toscaObjectPresentation = new HashMap<>();
 
-						JsonElement elementValue = entry.getValue();
-						PropertyDefinition propertyDefinition = allProperties.get(propName);
-						if (propertyDefinition == null) {
-							log.debug("The property {} was not found under data type {}",propName,dataTypeDefinition.getName());
-							continue;
-							// return null;
-						}
-						String type = propertyDefinition.getType();
-						ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
-						Object convValue;
-						if (propertyType != null) {
-							if (elementValue.isJsonPrimitive()) {
-								ToscaValueConverter valueConverter = propertyType.getValueConverter();
-								convValue = valueConverter.convertToToscaValue(elementValue.getAsString(), type,
-										dataTypes);
-							} else {
-								if (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(propertyType)) {
-									ToscaValueConverter valueConverter = propertyType.getValueConverter();
-									String json = gson.toJson(elementValue);
-									String innerTypeRecursive = propertyDefinition.getSchema().getProperty().getType();
-									convValue = valueConverter.convertToToscaValue(json, innerTypeRecursive, dataTypes);
-								} else {
-									convValue = handleComplexJsonValue(elementValue);
-								}
-							}
-						} else {
-							String json = gson.toJson(elementValue);
-							convValue = convertToToscaValue(json, type, dataTypes);
-						}
-						toscaObjectPresentation.put(propName, convValue);
-					}
-					convertedValue = toscaObjectPresentation;
-				}
-				toscaList.add(convertedValue);
-			});
-			return toscaList;
-		} catch (
+                    for (Entry<String, JsonElement> entry : entrySet) {
+                        String propName = entry.getKey();
 
-		JsonParseException e) {
-			log.debug("Failed to parse json : {}", value, e);
-			BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter");
-			return null;
-		}
-	}
+                        JsonElement elementValue = entry.getValue();
+                        PropertyDefinition propertyDefinition = allProperties.get(propName);
+                        if (propertyDefinition == null) {
+                            log.debug("The property {} was not found under data type {}",propName,dataTypeDefinition.getName());
+                            continue;
+                            // return null;
+                        }
+                        String type = propertyDefinition.getType();
+                        ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
+                        Object convValue;
+                        if (propertyType != null) {
+                            if (elementValue.isJsonPrimitive()) {
+                                ToscaValueConverter valueConverter = propertyType.getValueConverter();
+                                convValue = valueConverter.convertToToscaValue(elementValue.getAsString(), type,
+                                        dataTypes);
+                            } else {
+                                if (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(propertyType)) {
+                                    ToscaValueConverter valueConverter = propertyType.getValueConverter();
+                                    String json = gson.toJson(elementValue);
+                                    String innerTypeRecursive = propertyDefinition.getSchema().getProperty().getType();
+                                    convValue = valueConverter.convertToToscaValue(json, innerTypeRecursive, dataTypes);
+                                } else {
+                                    convValue = handleComplexJsonValue(elementValue);
+                                }
+                            }
+                        } else {
+                            String json = gson.toJson(elementValue);
+                            convValue = convertToToscaValue(json, type, dataTypes);
+                        }
+                        toscaObjectPresentation.put(propName, convValue);
+                    }
+                    convertedValue = toscaObjectPresentation;
+                }
+                toscaList.add(convertedValue);
+            });
+            return toscaList;
+        } catch (
+
+        JsonParseException e) {
+            log.debug("Failed to parse json : {}", value, e);
+            BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter");
+            return null;
+        }
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java
index 5b565bf..04636d8 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java
@@ -20,233 +20,222 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
+import com.google.gson.*;
+import com.google.gson.stream.JsonReader;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonSyntaxException;
-import com.google.gson.stream.JsonReader;
+import java.io.StringReader;
+import java.util.*;
+import java.util.Map.Entry;
 
 public class ToscaMapValueConverter extends ToscaValueBaseConverter implements ToscaValueConverter {
-	private static ToscaMapValueConverter mapConverter = new ToscaMapValueConverter();
+    private static ToscaMapValueConverter mapConverter = new ToscaMapValueConverter();
 
-	private JsonParser jsonParser = new JsonParser();
-	private static Logger log = LoggerFactory.getLogger(ToscaMapValueConverter.class.getName());
+    private JsonParser jsonParser = new JsonParser();
+    private static final Logger log = Logger.getLogger(ToscaMapValueConverter.class.getName());
 
-	public static ToscaMapValueConverter getInstance() {
-		return mapConverter;
-	}
+    public static ToscaMapValueConverter getInstance() {
+        return mapConverter;
+    }
 
-	private ToscaMapValueConverter() {
+    private ToscaMapValueConverter() {
 
-	}
+    }
 
-	@Override
-	public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		if (value == null) {
-			return value;
-		}
-		try {
-			ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
-			ToscaValueConverter innerConverter = null;
-			boolean isScalar = true;
-			List<PropertyDefinition> allPropertiesRecursive = new ArrayList<>();
-			if (innerToscaType != null) {
-				innerConverter = innerToscaType.getValueConverter();
-			} else {
+    @Override
+    public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        if (value == null) {
+            return value;
+        }
+        try {
+            ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
+            ToscaValueConverter innerConverter = null;
+            boolean isScalar = true;
+            List<PropertyDefinition> allPropertiesRecursive = new ArrayList<>();
+            if (innerToscaType != null) {
+                innerConverter = innerToscaType.getValueConverter();
+            } else {
 
-				DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
-				if (dataTypeDefinition != null) {
-					ToscaPropertyType toscaPropertyType = null;
-					if ((toscaPropertyType = isScalarType(dataTypeDefinition)) != null) {
-						innerConverter = toscaPropertyType.getValueConverter();
-					} else {
-						isScalar = false;
-						allPropertiesRecursive.addAll(dataTypeDefinition.getProperties());
-						DataTypeDefinition derivedFrom = dataTypeDefinition.getDerivedFrom();
-						while ( !derivedFrom.getName().equals("tosca.datatypes.Root") ){
-							allPropertiesRecursive.addAll(derivedFrom.getProperties());
-							derivedFrom = derivedFrom.getDerivedFrom();
-						}
-					}
-				} else {
-					log.debug("inner Tosca Type is null");
-					return value;
-				}
+                DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
+                if (dataTypeDefinition != null) {
+                    ToscaPropertyType toscaPropertyType = null;
+                    if ((toscaPropertyType = isScalarType(dataTypeDefinition)) != null) {
+                        innerConverter = toscaPropertyType.getValueConverter();
+                    } else {
+                        isScalar = false;
+                        allPropertiesRecursive.addAll(dataTypeDefinition.getProperties());
+                        DataTypeDefinition derivedFrom = dataTypeDefinition.getDerivedFrom();
+                        while ( !derivedFrom.getName().equals("tosca.datatypes.Root") ){
+                            allPropertiesRecursive.addAll(derivedFrom.getProperties());
+                            derivedFrom = derivedFrom.getDerivedFrom();
+                        }
+                    }
+                } else {
+                    log.debug("inner Tosca Type is null");
+                    return value;
+                }
 
-			}
-			JsonElement jsonElement = null;
-			try {
-				StringReader reader = new StringReader(value);
-				JsonReader jsonReader = new JsonReader(reader);
-				jsonReader.setLenient(true);
+            }
+            JsonElement jsonElement = null;
+            try {
+                StringReader reader = new StringReader(value);
+                JsonReader jsonReader = new JsonReader(reader);
+                jsonReader.setLenient(true);
 
-				jsonElement = jsonParser.parse(jsonReader);
+                jsonElement = jsonParser.parse(jsonReader);
 
-			} catch (JsonSyntaxException e) {
-				log.debug("convertToToscaValue failed to parse json value :", e);
-				return null;
-			}
-			if (jsonElement == null || true == jsonElement.isJsonNull()) {
-				log.debug("convertToToscaValue json element is null");
-				return null;
-			}
-			JsonObject asJsonObject = jsonElement.getAsJsonObject();
-			Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
+            } catch (JsonSyntaxException e) {
+                log.debug("convertToToscaValue failed to parse json value :", e);
+                return null;
+            }
+            if (jsonElement == null || jsonElement.isJsonNull()) {
+                log.debug("convertToToscaValue json element is null");
+                return null;
+            }
+            JsonObject asJsonObject = jsonElement.getAsJsonObject();
+            Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
 
-			Map<String, Object> toscaMap = new HashMap<>();
-			final boolean isScalarF = isScalar;
-			final ToscaValueConverter innerConverterFinal = innerConverter;
-			entrySet.forEach(e -> {
-				convertEntry(innerType, dataTypes, allPropertiesRecursive, toscaMap, isScalarF, innerConverterFinal, e);
-			});
-			return toscaMap;
-		} catch (JsonParseException e) {
-			log.debug("Failed to parse json : {}", value, e);
-			BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter");
-			return null;
-		}
-	}
+            Map<String, Object> toscaMap = new HashMap<>();
+            final boolean isScalarF = isScalar;
+            final ToscaValueConverter innerConverterFinal = innerConverter;
+            entrySet.forEach(e -> {
+                convertEntry(innerType, dataTypes, allPropertiesRecursive, toscaMap, isScalarF, innerConverterFinal, e);
+            });
+            return toscaMap;
+        } catch (JsonParseException e) {
+            log.debug("Failed to parse json : {}", value, e);
+            BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter");
+            return null;
+        }
+    }
 
-	private void convertEntry(String innerType, Map<String, DataTypeDefinition> dataTypes, List<PropertyDefinition> allPropertiesRecursive, Map<String, Object> toscaMap, final boolean isScalarF, final ToscaValueConverter innerConverterFinal,
-			Entry<String, JsonElement> e) {
-		log.debug("try convert element {}", e.getValue());
-		boolean scalar = false;
-		String propType = null; 
-		ToscaValueConverter innerConverterProp = innerConverterFinal;
-		if ( isScalarF ){
-			scalar = isScalarF;
-			propType = innerType;
-		}else{
-			for ( PropertyDefinition pd : allPropertiesRecursive ){
-				if ( pd.getName().equals(e.getKey()) ){
-					propType = pd.getType();
-					DataTypeDefinition pdDataType = dataTypes.get(propType);
-					ToscaPropertyType toscaPropType = isScalarType(pdDataType);
-					if ( toscaPropType == null ){
-						scalar = false;
-					}else{
-						scalar = true;
-						propType = toscaPropType.getType();
-						innerConverterProp = toscaPropType.getValueConverter();
-					}
-					break;
-				}
-			}
-		}
-		Object convertedValue = convertDataTypeToToscaObject(propType, dataTypes, innerConverterProp, scalar, e.getValue());
-		toscaMap.put(e.getKey(), convertedValue);
-	}
+    private void convertEntry(String innerType, Map<String, DataTypeDefinition> dataTypes, List<PropertyDefinition> allPropertiesRecursive, Map<String, Object> toscaMap, final boolean isScalarF, final ToscaValueConverter innerConverterFinal,
+            Entry<String, JsonElement> e) {
+        log.debug("try convert element {}", e.getValue());
+        boolean scalar = false;
+        String propType = null;
+        ToscaValueConverter innerConverterProp = innerConverterFinal;
+        if ( isScalarF ){
+            scalar = isScalarF;
+            propType = innerType;
+        }else{
+            for ( PropertyDefinition pd : allPropertiesRecursive ){
+                if ( pd.getName().equals(e.getKey()) ){
+                    propType = pd.getType();
+                    DataTypeDefinition pdDataType = dataTypes.get(propType);
+                    ToscaPropertyType toscaPropType = isScalarType(pdDataType);
+                    if ( toscaPropType == null ){
+                        scalar = false;
+                    }else{
+                        scalar = true;
+                        propType = toscaPropType.getType();
+                        innerConverterProp = toscaPropType.getValueConverter();
+                    }
+                    break;
+                }
+            }
+        }
+        Object convertedValue = convertDataTypeToToscaObject(propType, dataTypes, innerConverterProp, scalar, e.getValue(), false);
+        toscaMap.put(e.getKey(), convertedValue);
+    }
 
-	public Object convertDataTypeToToscaObject(String innerType, Map<String, DataTypeDefinition> dataTypes, ToscaValueConverter innerConverter, final boolean isScalarF, JsonElement entryValue) {
-		Object convertedValue = null;
-		if (isScalarF && entryValue.isJsonPrimitive()) {
-			log.debug("try convert scalar value {}", entryValue.getAsString());
-			if (entryValue.getAsString() == null) {
-				convertedValue = null;
-			} else {
-				convertedValue = innerConverter.convertToToscaValue(entryValue.getAsString(), innerType, dataTypes);
-			}
-		} else {
-			if ( entryValue.isJsonPrimitive() ){
-				return handleComplexJsonValue(entryValue);
-			}
-			
-			// ticket 228696523 created   / DE272734 / Bug 154492 Fix
-			if(entryValue instanceof JsonArray) {
-				ArrayList<Object> toscaObjectPresentationArray = new ArrayList<>();
-				JsonArray jsonArray = entryValue.getAsJsonArray();
-				
-				for (JsonElement jsonElement : jsonArray) {
-					Object convertedDataTypeToToscaMap = convertDataTypeToToscaMap(innerType, dataTypes, isScalarF, jsonElement);
-					toscaObjectPresentationArray.add(convertedDataTypeToToscaMap);
-				}
-				convertedValue = toscaObjectPresentationArray;
-			} else {
-				convertedValue = convertDataTypeToToscaMap(innerType, dataTypes, isScalarF, entryValue);				
-			}
-		}
-		return convertedValue;
-	}
+    public Object convertDataTypeToToscaObject(String innerType, Map<String, DataTypeDefinition> dataTypes, ToscaValueConverter innerConverter, final boolean isScalarF, JsonElement entryValue, boolean preserveEmptyValue) {
+        Object convertedValue = null;
+        if (isScalarF && entryValue.isJsonPrimitive()) {
+            log.debug("try convert scalar value {}", entryValue.getAsString());
+            if (entryValue.getAsString() == null) {
+                convertedValue = null;
+            } else {
+                convertedValue = innerConverter.convertToToscaValue(entryValue.getAsString(), innerType, dataTypes);
+            }
+        } else {
+            if ( entryValue.isJsonPrimitive() ){
+                return handleComplexJsonValue(entryValue);
+            }
 
-	private Object convertDataTypeToToscaMap(String innerType, Map<String, DataTypeDefinition> dataTypes,
-			final boolean isScalarF, JsonElement entryValue) {
-		Object convertedValue;
-		if (entryValue.isJsonPrimitive()) {
-			return json2JavaPrimitive(entryValue.getAsJsonPrimitive());
-		} 
-		JsonObject asJsonObjectIn = entryValue.getAsJsonObject();
+            // ticket 228696523 created   / DE272734 / Bug 154492 Fix
+            if(entryValue instanceof JsonArray) {
+                ArrayList<Object> toscaObjectPresentationArray = new ArrayList<>();
+                JsonArray jsonArray = entryValue.getAsJsonArray();
 
-		DataTypePropertyConverter.getInstance().mergeDataTypeDefaultValuesWithPropertyValue(asJsonObjectIn, innerType, dataTypes);
-		Map<String, Object> toscaObjectPresentation = new HashMap<>();
-		Set<Entry<String, JsonElement>> entrySetIn = asJsonObjectIn.entrySet();
-		
-		for (Entry<String, JsonElement> entry : entrySetIn) {
-			String propName = entry.getKey();
+                for (JsonElement jsonElement : jsonArray) {
+                    Object convertedDataTypeToToscaMap = convertDataTypeToToscaMap(innerType, dataTypes, isScalarF, jsonElement, preserveEmptyValue);
+                    toscaObjectPresentationArray.add(convertedDataTypeToToscaMap);
+                }
+                convertedValue = toscaObjectPresentationArray;
+            } else {
+                convertedValue = convertDataTypeToToscaMap(innerType, dataTypes, isScalarF, entryValue, preserveEmptyValue);
+            }
+        }
+        return convertedValue;
+    }
 
-			JsonElement elementValue = entry.getValue();
-			Object convValue;
-			if (isScalarF == false) {
-				DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
-				Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
-				PropertyDefinition propertyDefinition = allProperties.get(propName);
-				if (propertyDefinition == null) {
-					log.trace("The property {} was not found under data type . Parse as map", propName);
-					if (elementValue.isJsonPrimitive()) {
-						convValue = elementValue.getAsString();
-					} else {
-						convValue = handleComplexJsonValue(elementValue);
-					}
-				} else {
-					String type = propertyDefinition.getType();
-					ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
-					if (propertyType != null) {
-						if (elementValue.isJsonPrimitive()) {
-							ToscaValueConverter valueConverter = propertyType.getValueConverter();
-							convValue = valueConverter.convertToToscaValue(elementValue.getAsString(), type, dataTypes);
-						} else {
-							if (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(propertyType)) {
-								ToscaValueConverter valueConverter = propertyType.getValueConverter();
-								String json = gson.toJson(elementValue);
-								String innerTypeRecursive = propertyDefinition.getSchema().getProperty().getType();
-								convValue = valueConverter.convertToToscaValue(json, innerTypeRecursive, dataTypes);
-							} else {
-								convValue = handleComplexJsonValue(elementValue);
-							}
-						}
-					} else {
-						convValue = convertToToscaValue(elementValue.toString(), type, dataTypes);
-					}
-				}
-			} else {
-				if (elementValue.isJsonPrimitive()) {
-					convValue = json2JavaPrimitive(elementValue.getAsJsonPrimitive());
-				} else {
-					convValue = handleComplexJsonValue(elementValue);
-				}
-			}
-			if(!isEmptyObjectValue(convValue)){
-				toscaObjectPresentation.put(propName, convValue);
-			}
-		}
-		convertedValue = toscaObjectPresentation;
-		return convertedValue;
-	}
+    private Object convertDataTypeToToscaMap(String innerType, Map<String, DataTypeDefinition> dataTypes,
+            final boolean isScalarF, JsonElement entryValue, boolean preserveEmptyValue) {
+        Object convertedValue;
+        if (entryValue.isJsonPrimitive()) {
+            return json2JavaPrimitive(entryValue.getAsJsonPrimitive());
+        }
+        JsonObject asJsonObjectIn = entryValue.getAsJsonObject();
+
+        DataTypePropertyConverter.getInstance().mergeDataTypeDefaultValuesWithPropertyValue(asJsonObjectIn, innerType, dataTypes);
+        Map<String, Object> toscaObjectPresentation = new HashMap<>();
+        Set<Entry<String, JsonElement>> entrySetIn = asJsonObjectIn.entrySet();
+
+        for (Entry<String, JsonElement> entry : entrySetIn) {
+            String propName = entry.getKey();
+
+            JsonElement elementValue = entry.getValue();
+            Object convValue;
+            if (!isScalarF) {
+                DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
+                Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
+                PropertyDefinition propertyDefinition = allProperties.get(propName);
+                if (propertyDefinition == null) {
+                    log.trace("The property {} was not found under data type . Parse as map", propName);
+                    if (elementValue.isJsonPrimitive()) {
+                        convValue = elementValue.getAsString();
+                    } else {
+                        convValue = handleComplexJsonValue(elementValue);
+                    }
+                } else {
+                    String type = propertyDefinition.getType();
+                    ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
+                    if (propertyType != null) {
+                        if (elementValue.isJsonPrimitive()) {
+                            ToscaValueConverter valueConverter = propertyType.getValueConverter();
+                            convValue = valueConverter.convertToToscaValue(elementValue.getAsString(), type, dataTypes);
+                        } else {
+                            if (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(propertyType)) {
+                                ToscaValueConverter valueConverter = propertyType.getValueConverter();
+                                String json = gson.toJson(elementValue);
+                                String innerTypeRecursive = propertyDefinition.getSchema().getProperty().getType();
+                                convValue = valueConverter.convertToToscaValue(json, innerTypeRecursive, dataTypes);
+                            } else {
+                                convValue = handleComplexJsonValue(elementValue);
+                            }
+                        }
+                    } else {
+                        convValue = convertToToscaValue(elementValue.toString(), type, dataTypes);
+                    }
+                }
+            } else {
+                if (elementValue.isJsonPrimitive()) {
+                    convValue = json2JavaPrimitive(elementValue.getAsJsonPrimitive());
+                } else {
+                    convValue = handleComplexJsonValue(elementValue);
+                }
+            }
+            if(preserveEmptyValue || !isEmptyObjectValue(convValue)){
+                toscaObjectPresentation.put(propName, convValue);
+            }
+        }
+        convertedValue = toscaObjectPresentation;
+        return convertedValue;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.java
index e228d25..01cf47a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.java
@@ -20,24 +20,24 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class ToscaStringConvertor implements ToscaValueConverter {
-	private static ToscaStringConvertor stringConverter = new ToscaStringConvertor();
+    private static ToscaStringConvertor stringConverter = new ToscaStringConvertor();
 
-	public static ToscaStringConvertor getInstance() {
-		return stringConverter;
-	}
+    public static ToscaStringConvertor getInstance() {
+        return stringConverter;
+    }
 
-	private ToscaStringConvertor() {
+    private ToscaStringConvertor() {
 
-	}
+    }
 
-	@Override
-	public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		return value;
-	}
+    @Override
+    public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        return value;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java
index 7e2f876..e57650b 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java
@@ -20,158 +20,147 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
+import com.google.gson.*;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
+import java.util.*;
+import java.util.Map.Entry;
 
 public class ToscaValueBaseConverter {
-	protected Gson gson = new Gson();
-	private static Logger log = LoggerFactory.getLogger(ToscaValueBaseConverter.class.getName());
+    protected Gson gson = new Gson();
+    private static final Logger log = Logger.getLogger(ToscaValueBaseConverter.class.getName());
 
-	protected Map<String, PropertyDefinition> getAllProperties(DataTypeDefinition dataTypeDefinition) {
+    protected Map<String, PropertyDefinition> getAllProperties(DataTypeDefinition dataTypeDefinition) {
 
-		Map<String, PropertyDefinition> allParentsProps = new HashMap<>();
+        Map<String, PropertyDefinition> allParentsProps = new HashMap<>();
 
-		while (dataTypeDefinition != null) {
+        while (dataTypeDefinition != null) {
 
-			List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties();
-			if (currentParentsProps != null) {
-				currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p));
-			}
+            List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties();
+            if (currentParentsProps != null) {
+                currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p));
+            }
 
-			dataTypeDefinition = dataTypeDefinition.getDerivedFrom();
-		}
+            dataTypeDefinition = dataTypeDefinition.getDerivedFrom();
+        }
 
-		return allParentsProps;
-	}
+        return allParentsProps;
+    }
 
-	public ToscaPropertyType isScalarType(DataTypeDefinition dataTypeDef) {
+    public ToscaPropertyType isScalarType(DataTypeDefinition dataTypeDef) {
 
-		ToscaPropertyType result = null;
+        ToscaPropertyType result = null;
 
-		DataTypeDefinition dataType = dataTypeDef;
+        DataTypeDefinition dataType = dataTypeDef;
 
-		while (dataType != null) {
+        while (dataType != null) {
 
-			String name = dataType.getName();
-			ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name);
-			if (typeIfScalar != null) {
-				result = typeIfScalar;
-				break;
-			}
+            String name = dataType.getName();
+            ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name);
+            if (typeIfScalar != null) {
+                result = typeIfScalar;
+                break;
+            }
 
-			dataType = dataType.getDerivedFrom();
-		}
+            dataType = dataType.getDerivedFrom();
+        }
 
-		return result;
-	}
+        return result;
+    }
 
-	public Object handleComplexJsonValue(JsonElement elementValue) {
-		Object jsonValue = null;
+    public Object handleComplexJsonValue(JsonElement elementValue) {
+        Object jsonValue = null;
 
-		Map<String, Object> value = new HashMap<String, Object>();
-		if (elementValue.isJsonObject()) {
-			JsonObject jsonOb = elementValue.getAsJsonObject();
-			Set<Entry<String, JsonElement>> entrySet = jsonOb.entrySet();
-			Iterator<Entry<String, JsonElement>> iteratorEntry = entrySet.iterator();
-			while (iteratorEntry.hasNext()) {
-				Entry<String, JsonElement> entry = iteratorEntry.next();
-				if (entry.getValue().isJsonArray()) {
-					List<Object> array = handleJsonArray(entry.getValue());
-					value.put(entry.getKey(), array);
-				} else {
-					Object object;
-					if (entry.getValue().isJsonPrimitive()) {
-						object = json2JavaPrimitive(entry.getValue().getAsJsonPrimitive());
-					} else {
-						object = handleComplexJsonValue(entry.getValue());
-					}
-					value.put(entry.getKey(), object);
-				}
-			}
-			jsonValue = value;
-		} else {
-			if (elementValue.isJsonArray()) {
-				jsonValue = handleJsonArray(elementValue);
-			} else {
-				if (elementValue.isJsonPrimitive()) {
-					jsonValue = json2JavaPrimitive(elementValue.getAsJsonPrimitive());
-				} else {
-					log.debug("not supported json type {} ", elementValue);
-				}
-			}
-		}
+        Map<String, Object> value = new HashMap<>();
+        if (elementValue.isJsonObject()) {
+            JsonObject jsonOb = elementValue.getAsJsonObject();
+            Set<Entry<String, JsonElement>> entrySet = jsonOb.entrySet();
+            Iterator<Entry<String, JsonElement>> iteratorEntry = entrySet.iterator();
+            while (iteratorEntry.hasNext()) {
+                Entry<String, JsonElement> entry = iteratorEntry.next();
+                if (entry.getValue().isJsonArray()) {
+                    List<Object> array = handleJsonArray(entry.getValue());
+                    value.put(entry.getKey(), array);
+                } else {
+                    Object object;
+                    if (entry.getValue().isJsonPrimitive()) {
+                        object = json2JavaPrimitive(entry.getValue().getAsJsonPrimitive());
+                    } else {
+                        object = handleComplexJsonValue(entry.getValue());
+                    }
+                    value.put(entry.getKey(), object);
+                }
+            }
+            jsonValue = value;
+        } else {
+            if (elementValue.isJsonArray()) {
+                jsonValue = handleJsonArray(elementValue);
+            } else {
+                if (elementValue.isJsonPrimitive()) {
+                    jsonValue = json2JavaPrimitive(elementValue.getAsJsonPrimitive());
+                } else {
+                    log.debug("not supported json type {} ", elementValue);
+                }
+            }
+        }
 
-		return jsonValue;
-	}
+        return jsonValue;
+    }
 
-	private List<Object> handleJsonArray(JsonElement entry) {
-		List<Object> array = new ArrayList<>();
-		JsonArray jsonArray = entry.getAsJsonArray();
-		Iterator<JsonElement> iterator = jsonArray.iterator();
-		while (iterator.hasNext()) {
-			Object object;
-			JsonElement element = iterator.next();
-			if (element.isJsonPrimitive()) {
-				object = json2JavaPrimitive(element.getAsJsonPrimitive());
-			} else {
-				object = handleComplexJsonValue(element);
-			}
-			array.add(object);
-		}
-		return array;
-	}
+    private List<Object> handleJsonArray(JsonElement entry) {
+        List<Object> array = new ArrayList<>();
+        JsonArray jsonArray = entry.getAsJsonArray();
+        Iterator<JsonElement> iterator = jsonArray.iterator();
+        while (iterator.hasNext()) {
+            Object object;
+            JsonElement element = iterator.next();
+            if (element.isJsonPrimitive()) {
+                object = json2JavaPrimitive(element.getAsJsonPrimitive());
+            } else {
+                object = handleComplexJsonValue(element);
+            }
+            array.add(object);
+        }
+        return array;
+    }
 
-	public Object json2JavaPrimitive(JsonPrimitive prim) {
-		if (prim.isBoolean()) {
-			return prim.getAsBoolean();
-		} else if (prim.isString()) {
-			return prim.getAsString();
-		} else if (prim.isNumber()) {
-			String strRepesentation = prim.getAsString();
-			if (strRepesentation.contains(".")) {
-				return prim.getAsDouble();
-			} else {
-				return prim.getAsInt();
-			}
-		} else {
-			throw new IllegalStateException();
-		}
-	}
+    public Object json2JavaPrimitive(JsonPrimitive prim) {
+        if (prim.isBoolean()) {
+            return prim.getAsBoolean();
+        } else if (prim.isString()) {
+            return prim.getAsString();
+        } else if (prim.isNumber()) {
+            String strRepesentation = prim.getAsString();
+            if (strRepesentation.contains(".")) {
+                return prim.getAsDouble();
+            } else {
+                return prim.getAsInt();
+            }
+        } else {
+            throw new IllegalStateException();
+        }
+    }
 
-	/**
-	 * checks is received Object empty or equals null or not It is relevant only
-	 * if received Object is instance of String, Map or List class.
-	 * 
-	 * @param convertedValue
-	 * @return
-	 */
-	static public boolean isEmptyObjectValue(Object convertedValue) {
-		if (convertedValue == null) {
-			return true;
-		} else if (convertedValue instanceof String && ((String) convertedValue).isEmpty()) {
-			return true;
-		} else if (convertedValue instanceof Map && ((Map) convertedValue).isEmpty()) {
-			return true;
-		} else if (convertedValue instanceof List && ((List) convertedValue).isEmpty()) {
-			return true;
-		}
-		return false;
-	}
+    /**
+     * checks is received Object empty or equals null or not It is relevant only
+     * if received Object is instance of String, Map or List class.
+     *
+     * @param convertedValue
+     * @return
+     */
+    static public boolean isEmptyObjectValue(Object convertedValue) {
+        if (convertedValue == null) {
+            return true;
+        } else if (convertedValue instanceof String && ((String) convertedValue).isEmpty()) {
+            return true;
+        } else if (convertedValue instanceof Map && ((Map) convertedValue).isEmpty()) {
+            return true;
+        } else if (convertedValue instanceof List && ((List) convertedValue).isEmpty()) {
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.java
index 1b5d469..a9d3cb9 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.java
@@ -20,11 +20,11 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public interface ToscaValueConverter {
-	Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes);
+    Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes);
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.java
index b6eb242..ca0724d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.java
@@ -20,24 +20,24 @@
 
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class ToscaValueDefaultConverter implements ToscaValueConverter {
-	private static ToscaValueDefaultConverter deafultConverter = new ToscaValueDefaultConverter();
+    private static ToscaValueDefaultConverter deafultConverter = new ToscaValueDefaultConverter();
 
-	public static ToscaValueDefaultConverter getInstance() {
-		return deafultConverter;
-	}
+    public static ToscaValueDefaultConverter getInstance() {
+        return deafultConverter;
+    }
 
-	private ToscaValueDefaultConverter() {
+    private ToscaValueDefaultConverter() {
 
-	}
+    }
 
-	@Override
-	public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
-		return value;
-	}
+    @Override
+    public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+        return value;
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.java
index def0e7c..443334d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.java
@@ -20,36 +20,36 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+
 import java.util.Arrays;
 import java.util.Map;
 
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
 public class BooleanValidator implements PropertyTypeValidator {
 
-	private static BooleanValidator booleanValidator = new BooleanValidator();
-	private static String[] validValues = { "true", "t", "on", "yes", "y", "1", "false", "f", "off", "no", "n", "0" };
+    private static BooleanValidator booleanValidator = new BooleanValidator();
+    private static String[] validValues = { "true", "t", "on", "yes", "y", "1", "false", "f", "off", "no", "n", "0" };
 
-	public static BooleanValidator getInstance() {
-		return booleanValidator;
-	}
+    public static BooleanValidator getInstance() {
+        return booleanValidator;
+    }
 
-	private BooleanValidator() {
+    private BooleanValidator() {
 
-	}
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (value == null || true == value.isEmpty()) {
-			return true;
-		}
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
 
-		return (Arrays.stream(validValues).filter(str -> str.equalsIgnoreCase(value)).toArray().length == 1);
-	}
+        return (Arrays.stream(validValues).filter(str -> str.equalsIgnoreCase(value)).toArray().length == 1);
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, null, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, null, null);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java
index ed58bc2..c64e47a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java
@@ -20,420 +20,414 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
+import com.google.gson.*;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
-import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonPrimitive;
-import com.google.gson.JsonSyntaxException;
-
 public class DataTypeValidatorConverter {
 
-	private static DataTypeValidatorConverter dataTypeValidatorConverter = new DataTypeValidatorConverter();
+    private static DataTypeValidatorConverter dataTypeValidatorConverter = new DataTypeValidatorConverter();
 
-	public static DataTypeValidatorConverter getInstance() {
-		return dataTypeValidatorConverter;
-	}
+    public static DataTypeValidatorConverter getInstance() {
+        return dataTypeValidatorConverter;
+    }
 
-	private DataTypeValidatorConverter() {
+    private DataTypeValidatorConverter() {
 
-	}
+    }
 
-	private static Logger log = LoggerFactory.getLogger(DataTypeValidatorConverter.class.getName());
+    private static final Logger log = Logger.getLogger(DataTypeValidatorConverter.class.getName());
 
-	JsonParser jsonParser = new JsonParser();
+    JsonParser jsonParser = new JsonParser();
 
-	ImmutablePair<JsonElement, Boolean> falseResult = new ImmutablePair<JsonElement, Boolean>(null, false);
-	ImmutablePair<JsonElement, Boolean> trueEmptyResult = new ImmutablePair<JsonElement, Boolean>(null, true);
+    ImmutablePair<JsonElement, Boolean> falseResult = new ImmutablePair<>(null, false);
+    ImmutablePair<JsonElement, Boolean> trueEmptyResult = new ImmutablePair<>(null, true);
 
-	ImmutablePair<String, Boolean> trueStringEmptyResult = new ImmutablePair<String, Boolean>(null, true);
-	ImmutablePair<String, Boolean> falseStringEmptyResult = new ImmutablePair<String, Boolean>(null, true);
+    ImmutablePair<String, Boolean> trueStringEmptyResult = new ImmutablePair<>(null, true);
+    ImmutablePair<String, Boolean> falseStringEmptyResult = new ImmutablePair<>(null, true);
 
-	private ToscaPropertyType isDataTypeDerviedFromScalarType(DataTypeDefinition dataTypeDef) {
+    private ToscaPropertyType isDataTypeDerviedFromScalarType(DataTypeDefinition dataTypeDef) {
 
-		ToscaPropertyType result = null;
+        ToscaPropertyType result = null;
 
-		DataTypeDefinition dataType = dataTypeDef;
+        DataTypeDefinition dataType = dataTypeDef;
 
-		while (dataType != null) {
+        while (dataType != null) {
 
-			String name = dataType.getName();
-			ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name);
-			if (typeIfScalar != null) {
-				result = typeIfScalar;
-				break;
-			}
+            String name = dataType.getName();
+            ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name);
+            if (typeIfScalar != null) {
+                result = typeIfScalar;
+                break;
+            }
 
-			dataType = dataType.getDerivedFrom();
-		}
+            dataType = dataType.getDerivedFrom();
+        }
 
-		return result;
-	}
+        return result;
+    }
 
-	private ImmutablePair<JsonElement, Boolean> validateAndUpdate(JsonElement jsonElement, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
+    private ImmutablePair<JsonElement, Boolean> validateAndUpdate(JsonElement jsonElement, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
 
-		Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
+        Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
 
-		ToscaPropertyType toscaPropertyType = null;
-		if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) {
+        ToscaPropertyType toscaPropertyType = null;
+        if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) {
 
-			PropertyTypeValidator validator = toscaPropertyType.getValidator();
-			PropertyValueConverter converter = toscaPropertyType.getConverter();
-			if (jsonElement == null || true == jsonElement.isJsonNull()) {
-				boolean valid = validator.isValid(null, null, allDataTypes);
-				if (!valid) {
-					log.trace("Failed in validation of property {} from type {}",  dataTypeDefinition.getName(), dataTypeDefinition.getName());
-					return falseResult;
-				}
-				return new ImmutablePair<JsonElement, Boolean>(jsonElement, true);
+            PropertyTypeValidator validator = toscaPropertyType.getValidator();
+            PropertyValueConverter converter = toscaPropertyType.getConverter();
+            if (jsonElement == null || jsonElement.isJsonNull()) {
+                boolean valid = validator.isValid(null, null, allDataTypes);
+                if (!valid) {
+                    log.trace("Failed in validation of property {} from type {}",  dataTypeDefinition.getName(), dataTypeDefinition.getName());
+                    return falseResult;
+                }
+                return new ImmutablePair<>(jsonElement, true);
 
-			} else {
-				if (jsonElement.isJsonPrimitive()) {
-					String value = null;
-					if (jsonElement != null) {
-						if (jsonElement.toString().isEmpty()) {
-							value = "";
-						} else {
-							value = jsonElement.toString();
-						}
-					}
-					boolean valid = validator.isValid(value, null, null);
-					if (!valid) {
-						log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(), dataTypeDefinition.getName(), value);
-						return falseResult;
-					}
+            } else {
+                if (jsonElement.isJsonPrimitive()) {
+                    String value = null;
+                    if (jsonElement != null) {
+                        if (jsonElement.toString().isEmpty()) {
+                            value = "";
+                        } else {
+                            value = jsonElement.toString();
+                        }
+                    }
+                    boolean valid = validator.isValid(value, null, null);
+                    if (!valid) {
+                        log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(), dataTypeDefinition.getName(), value);
+                        return falseResult;
+                    }
 
-					String convertedValue = converter.convert(value, null, allDataTypes);
-					JsonElement element = null;
-					try {
-						element = jsonParser.parse(convertedValue);
-					} catch (JsonSyntaxException e) {
-						log.debug("Failed to parse value {} of property {} {}", convertedValue, dataTypeDefinition.getName(), e);
-						return falseResult;
-					}
+                    String convertedValue = converter.convert(value, null, allDataTypes);
+                    JsonElement element = null;
+                    try {
+                        element = jsonParser.parse(convertedValue);
+                    } catch (JsonSyntaxException e) {
+                        log.debug("Failed to parse value {} of property {} {}", convertedValue, dataTypeDefinition.getName(), e);
+                        return falseResult;
+                    }
 
-					return new ImmutablePair<JsonElement, Boolean>(element, true);
+                    return new ImmutablePair<>(element, true);
 
-				} else {
-					// MAP, LIST, OTHER types cannot be applied data type
-					// definition scalar type. We currently cannot derived from
-					// map/list. (cannot add the entry schema to it)
-					log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one", dataTypeDefinition.getName());
+                } else {
+                    // MAP, LIST, OTHER types cannot be applied data type
+                    // definition scalar type. We currently cannot derived from
+                    // map/list. (cannot add the entry schema to it)
+                    log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one", dataTypeDefinition.getName());
 
-					return falseResult;
-				}
-			}
-		} else {
+                    return falseResult;
+                }
+            }
+        } else {
 
-			if (jsonElement == null || jsonElement.isJsonNull()) {
+            if (jsonElement == null || jsonElement.isJsonNull()) {
 
-				return new ImmutablePair<JsonElement, Boolean>(jsonElement, true);
+                return new ImmutablePair<>(jsonElement, true);
 
-			} else {
+            } else {
 
-				if (jsonElement.isJsonObject()) {
+                if (jsonElement.isJsonObject()) {
 
-					JsonObject buildJsonObject = new JsonObject();
+                    JsonObject buildJsonObject = new JsonObject();
 
-					JsonObject asJsonObject = jsonElement.getAsJsonObject();
-					Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
+                    JsonObject asJsonObject = jsonElement.getAsJsonObject();
+                    Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
 
-					for (Entry<String, JsonElement> entry : entrySet) {
-						String propName = entry.getKey();
+                    for (Entry<String, JsonElement> entry : entrySet) {
+                        String propName = entry.getKey();
 
-						JsonElement elementValue = entry.getValue();
+                        JsonElement elementValue = entry.getValue();
 
-						PropertyDefinition propertyDefinition = allProperties.get(propName);
-						if (propertyDefinition == null) {
-							log.debug("The property {} was not found under data type {}" ,propName, dataTypeDefinition.getName());
-							return falseResult;
-						}
-						String type = propertyDefinition.getType();
-						boolean isScalarType = ToscaPropertyType.isScalarType(type);
+                        PropertyDefinition propertyDefinition = allProperties.get(propName);
+                        if (propertyDefinition == null) {
+                            log.debug("The property {} was not found under data type {}" ,propName, dataTypeDefinition.getName());
+                            return falseResult;
+                        }
+                        String type = propertyDefinition.getType();
+                        boolean isScalarType = ToscaPropertyType.isScalarType(type);
 
-						if (isScalarType) {
-							ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
-							if (propertyType == null) {
-								log.debug("cannot find the {} under default tosca property types", type);
-								return falseResult;
-							}
-							PropertyTypeValidator validator = propertyType.getValidator();
-							String innerType = null;
-							if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) {
-								if (propertyDefinition.getSchema() != null && propertyDefinition.getSchema().getProperty() != null) {
-									innerType = propertyDefinition.getSchema().getProperty().getType();
-									if (innerType == null) {
-										log.debug("Property type {} must have inner type in its declaration.", propertyType);
-										return falseResult;
-									}
-								}
-							}
+                        if (isScalarType) {
+                            ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
+                            if (propertyType == null) {
+                                log.debug("cannot find the {} under default tosca property types", type);
+                                return falseResult;
+                            }
+                            PropertyTypeValidator validator = propertyType.getValidator();
+                            String innerType = null;
+                            if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) {
+                                if (propertyDefinition.getSchema() != null && propertyDefinition.getSchema().getProperty() != null) {
+                                    innerType = propertyDefinition.getSchema().getProperty().getType();
+                                    if (innerType == null) {
+                                        log.debug("Property type {} must have inner type in its declaration.", propertyType);
+                                        return falseResult;
+                                    }
+                                }
+                            }
 
-							String value = null;
-							if (elementValue != null) {
-								if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) {
-									value = "";
-								} else {
-									value = elementValue.toString();
-								}
-							}
+                            String value = null;
+                            if (elementValue != null) {
+                                if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) {
+                                    value = "";
+                                } else {
+                                    value = elementValue.toString();
+                                }
+                            }
 
-							boolean isValid = validator.isValid(value, innerType, allDataTypes);
-							if (false == isValid) {
-								log.debug("Failed to validate the value {} from type {}", value, propertyType);
-								return falseResult;
-							}
+                            boolean isValid = validator.isValid(value, innerType, allDataTypes);
+                            if (!isValid) {
+                                log.debug("Failed to validate the value {} from type {}", value, propertyType);
+                                return falseResult;
+                            }
 
-							PropertyValueConverter converter = propertyType.getConverter();
-							String convertedValue = converter.convert(value, innerType, allDataTypes);
+                            PropertyValueConverter converter = propertyType.getConverter();
+                            String convertedValue = converter.convert(value, innerType, allDataTypes);
 
-							JsonElement element = null;
-							if (convertedValue != null) {
-								if (convertedValue.isEmpty()) {
-									element = new JsonPrimitive("");
-								} else {
-									try {
-										element = jsonParser.parse(convertedValue);
-									} catch (JsonSyntaxException e) {
-										log.debug("Failed to parse value {} of type {}", convertedValue, propertyType, e);
-										return falseResult;
-									}
-								}
-							}
-							buildJsonObject.add(propName, element);
+                            JsonElement element = null;
+                            if (convertedValue != null) {
+                                if (convertedValue.isEmpty()) {
+                                    element = new JsonPrimitive("");
+                                } else {
+                                    try {
+                                        element = jsonParser.parse(convertedValue);
+                                    } catch (JsonSyntaxException e) {
+                                        log.debug("Failed to parse value {} of type {}", convertedValue, propertyType, e);
+                                        return falseResult;
+                                    }
+                                }
+                            }
+                            buildJsonObject.add(propName, element);
 
-						} else {
+                        } else {
 
-							DataTypeDefinition typeDefinition = allDataTypes.get(type);
-							if (typeDefinition == null) {
-								log.debug("The data type {} cannot be found in the given data type list.", type);
-								return falseResult;
-							}
+                            DataTypeDefinition typeDefinition = allDataTypes.get(type);
+                            if (typeDefinition == null) {
+                                log.debug("The data type {} cannot be found in the given data type list.", type);
+                                return falseResult;
+                            }
 
-							ImmutablePair<JsonElement, Boolean> isValid = validateAndUpdate(elementValue, typeDefinition, allDataTypes);
+                            ImmutablePair<JsonElement, Boolean> isValid = validateAndUpdate(elementValue, typeDefinition, allDataTypes);
 
-							if (!isValid.getRight().booleanValue()) {
-								log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null), typeDefinition.getName());
-								return falseResult;
-							}
+                            if (!isValid.getRight().booleanValue()) {
+                                log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null), typeDefinition.getName());
+                                return falseResult;
+                            }
 
-							buildJsonObject.add(propName, isValid.getLeft());
-						}
+                            buildJsonObject.add(propName, isValid.getLeft());
+                        }
 
-					}
+                    }
 
-					return new ImmutablePair<JsonElement, Boolean>(buildJsonObject, true);
-				} else {
-					log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null), dataTypeDefinition.getName());
-					return falseResult;
-				}
+                    return new ImmutablePair<>(buildJsonObject, true);
+                } else {
+                    log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null), dataTypeDefinition.getName());
+                    return falseResult;
+                }
 
-			}
-		}
+            }
+        }
 
-	}
+    }
 
-	public ImmutablePair<JsonElement, Boolean> validateAndUpdate(String value, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
+    public ImmutablePair<JsonElement, Boolean> validateAndUpdate(String value, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
 
-		ImmutablePair<JsonElement, Boolean> result = falseResult;
+        ImmutablePair<JsonElement, Boolean> result = falseResult;
 
-		if (value == null || value.isEmpty()) {
-			return trueEmptyResult;
-		}
+        if (value == null || value.isEmpty()) {
+            return trueEmptyResult;
+        }
 
-		JsonElement jsonElement = null;
-		try {
-			jsonElement = jsonParser.parse(value);
-		} catch (JsonSyntaxException e) {
-			return falseResult;
-		}
+        JsonElement jsonElement = null;
+        try {
+            jsonElement = jsonParser.parse(value);
+        } catch (JsonSyntaxException e) {
+            return falseResult;
+        }
 
-		result = validateAndUpdate(jsonElement, dataTypeDefinition, allDataTypes);
+        result = validateAndUpdate(jsonElement, dataTypeDefinition, allDataTypes);
 
-		return result;
-	}
+        return result;
+    }
 
-	private Map<String, PropertyDefinition> getAllProperties(DataTypeDefinition dataTypeDefinition) {
+    private Map<String, PropertyDefinition> getAllProperties(DataTypeDefinition dataTypeDefinition) {
 
-		Map<String, PropertyDefinition> allParentsProps = new HashMap<String, PropertyDefinition>();
+        Map<String, PropertyDefinition> allParentsProps = new HashMap<>();
 
-		while (dataTypeDefinition != null) {
+        while (dataTypeDefinition != null) {
 
-			List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties();
-			if (currentParentsProps != null) {
-				currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p));
-			}
+            List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties();
+            if (currentParentsProps != null) {
+                currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p));
+            }
 
-			dataTypeDefinition = dataTypeDefinition.getDerivedFrom();
-		}
+            dataTypeDefinition = dataTypeDefinition.getDerivedFrom();
+        }
 
-		return allParentsProps;
-	}
+        return allParentsProps;
+    }
 
-	public boolean isValid(String value, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
+    public boolean isValid(String value, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
 
-		boolean result = false;
+        boolean result = false;
 
-		if (value == null || value.isEmpty()) {
-			return true;
-		}
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
 
-		JsonElement jsonElement = null;
-		try {
-			jsonElement = jsonParser.parse(value);
-		} catch (JsonSyntaxException e) {
-			log.debug("Failed to parse the value {} from type {}", value, dataTypeDefinition, e);
-			return false;
-		}
+        JsonElement jsonElement = null;
+        try {
+            jsonElement = jsonParser.parse(value);
+        } catch (JsonSyntaxException e) {
+            log.debug("Failed to parse the value {} from type {}", value, dataTypeDefinition, e);
+            return false;
+        }
 
-		result = isValid(jsonElement, dataTypeDefinition, allDataTypes);
+        result = isValid(jsonElement, dataTypeDefinition, allDataTypes);
 
-		return result;
-	}
+        return result;
+    }
 
-	private boolean isValid(JsonElement jsonElement, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
+    private boolean isValid(JsonElement jsonElement, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
 
-		Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
+        Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
 
-		ToscaPropertyType toscaPropertyType = null;
-		if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) {
+        ToscaPropertyType toscaPropertyType = null;
+        if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) {
 
-			PropertyTypeValidator validator = toscaPropertyType.getValidator();
-			if (jsonElement == null || true == jsonElement.isJsonNull()) {
-				boolean valid = validator.isValid(null, null, allDataTypes);
-				if (false == valid) {
-					log.trace("Failed in validation of property {} from type {}", dataTypeDefinition.getName(), dataTypeDefinition.getName());
-					return false;
-				}
+            PropertyTypeValidator validator = toscaPropertyType.getValidator();
+            if (jsonElement == null || jsonElement.isJsonNull()) {
+                boolean valid = validator.isValid(null, null, allDataTypes);
+                if (!valid) {
+                    log.trace("Failed in validation of property {} from type {}", dataTypeDefinition.getName(), dataTypeDefinition.getName());
+                    return false;
+                }
 
-				return true;
+                return true;
 
-			} else {
-				if (true == jsonElement.isJsonPrimitive()) {
-					String value = null;
-					if (jsonElement != null) {
-						if (jsonElement.toString().isEmpty()) {
-							value = "";
-						} else {
-							value = jsonElement.toString();
-						}
-					}
-					boolean valid = validator.isValid(value, null, allDataTypes);
-					if (false == valid) {
-						log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(), dataTypeDefinition.getName(), value);
-						return false;
-					}
+            } else {
+                if (jsonElement.isJsonPrimitive()) {
+                    String value = null;
+                    if (jsonElement != null) {
+                        if (jsonElement.toString().isEmpty()) {
+                            value = "";
+                        } else {
+                            value = jsonElement.toString();
+                        }
+                    }
+                    boolean valid = validator.isValid(value, null, allDataTypes);
+                    if (!valid) {
+                        log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(), dataTypeDefinition.getName(), value);
+                        return false;
+                    }
 
-					return true;
+                    return true;
 
-				} else {
-					// MAP, LIST, OTHER types cannot be applied data type
-					// definition scalar type. We currently cannot derived from
-					// map/list. (cannot add the entry schema to it)
-					log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one", dataTypeDefinition.getName());
+                } else {
+                    // MAP, LIST, OTHER types cannot be applied data type
+                    // definition scalar type. We currently cannot derived from
+                    // map/list. (cannot add the entry schema to it)
+                    log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one", dataTypeDefinition.getName());
 
-					return false;
-				}
-			}
-		} else {
+                    return false;
+                }
+            }
+        } else {
 
-			if (jsonElement == null || jsonElement.isJsonNull()) {
+            if (jsonElement == null || jsonElement.isJsonNull()) {
 
-				return true;
+                return true;
 
-			} else {
+            } else {
 
-				if (jsonElement.isJsonObject()) {
+                if (jsonElement.isJsonObject()) {
 
-					JsonObject asJsonObject = jsonElement.getAsJsonObject();
-					Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
+                    JsonObject asJsonObject = jsonElement.getAsJsonObject();
+                    Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
 
-					for (Entry<String, JsonElement> entry : entrySet) {
-						String propName = entry.getKey();
+                    for (Entry<String, JsonElement> entry : entrySet) {
+                        String propName = entry.getKey();
 
-						JsonElement elementValue = entry.getValue();
+                        JsonElement elementValue = entry.getValue();
 
-						PropertyDefinition propertyDefinition = allProperties.get(propName);
-						if (propertyDefinition == null) {
-							log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName());
-							return false;
-						}
-						String type = propertyDefinition.getType();
-						boolean isScalarType = ToscaPropertyType.isScalarType(type);
+                        PropertyDefinition propertyDefinition = allProperties.get(propName);
+                        if (propertyDefinition == null) {
+                            log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName());
+                            return false;
+                        }
+                        String type = propertyDefinition.getType();
+                        boolean isScalarType = ToscaPropertyType.isScalarType(type);
 
-						if (true == isScalarType) {
-							ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
-							if (propertyType == null) {
-								log.debug("cannot find the {} under default tosca property types", type);
-								return false;
-							}
-							PropertyTypeValidator validator = propertyType.getValidator();
-							String innerType = null;
-							if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) {
-								if (propertyDefinition.getSchema() != null && propertyDefinition.getSchema().getProperty() != null) {
-									innerType = propertyDefinition.getSchema().getProperty().getType();
-									if (innerType == null) {
-										log.debug("Property type {} must have inner type in its declaration.", propertyType);
-										return false;
-									}
-								}
-							}
+                        if (isScalarType) {
+                            ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
+                            if (propertyType == null) {
+                                log.debug("cannot find the {} under default tosca property types", type);
+                                return false;
+                            }
+                            PropertyTypeValidator validator = propertyType.getValidator();
+                            String innerType = null;
+                            if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) {
+                                if (propertyDefinition.getSchema() != null && propertyDefinition.getSchema().getProperty() != null) {
+                                    innerType = propertyDefinition.getSchema().getProperty().getType();
+                                    if (innerType == null) {
+                                        log.debug("Property type {} must have inner type in its declaration.", propertyType);
+                                        return false;
+                                    }
+                                }
+                            }
 
-							String value = null;
-							if (elementValue != null) {
-								if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) {
-									value = "";
-								} else {
-									value = elementValue.toString();
-								}
-							}
+                            String value = null;
+                            if (elementValue != null) {
+                                if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) {
+                                    value = "";
+                                } else {
+                                    value = elementValue.toString();
+                                }
+                            }
 
-							boolean isValid = validator.isValid(value, innerType, allDataTypes);
-							if (false == isValid) {
-								log.debug("Failed to validate the value {} from type {}", value, propertyType);
-								return false;
-							}
+                            boolean isValid = validator.isValid(value, innerType, allDataTypes);
+                            if (!isValid) {
+                                log.debug("Failed to validate the value {} from type {}", value, propertyType);
+                                return false;
+                            }
 
-						} else {
+                        } else {
 
-							DataTypeDefinition typeDefinition = allDataTypes.get(type);
-							if (typeDefinition == null) {
-								log.debug("The data type {} cannot be found in the given data type list.", type);
-								return false;
-							}
+                            DataTypeDefinition typeDefinition = allDataTypes.get(type);
+                            if (typeDefinition == null) {
+                                log.debug("The data type {} cannot be found in the given data type list.", type);
+                                return false;
+                            }
 
-							boolean isValid = isValid(elementValue, typeDefinition, allDataTypes);
+                            boolean isValid = isValid(elementValue, typeDefinition, allDataTypes);
 
-							if (false == isValid) {
-								log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null), typeDefinition.getName());
-								return false;
-							}
+                            if (!isValid) {
+                                log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null), typeDefinition.getName());
+                                return false;
+                            }
 
-						}
+                        }
 
-					}
+                    }
 
-					return true;
-				} else {
-					log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null), dataTypeDefinition.getName());
-					return false;
-				}
+                    return true;
+                } else {
+                    log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null), dataTypeDefinition.getName());
+                    return false;
+                }
 
-			}
-		}
+            }
+        }
 
-	}
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.java
index 2518eaa..f9121d1 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.java
@@ -20,41 +20,41 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class FloatValidator implements PropertyTypeValidator {
 
-	private static FloatValidator FloatValidator = new FloatValidator();
+    private static FloatValidator FloatValidator = new FloatValidator();
 
-	public static FloatValidator getInstance() {
-		return FloatValidator;
-	}
+    public static FloatValidator getInstance() {
+        return FloatValidator;
+    }
 
-	private FloatValidator() {
+    private FloatValidator() {
 
-	}
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (value == null || true == value.isEmpty()) {
-			return true;
-		}
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
 
-		try {
-			Float.parseFloat(value);
-		} catch (IllegalArgumentException e) {
-			return false;
-		}
+        try {
+            Float.parseFloat(value);
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
 
-		return true;
-	}
+        return true;
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.java
index ec4051e..f527206 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.java
@@ -20,42 +20,42 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class HeatBooleanValidator implements PropertyTypeValidator {
 
-	private static HeatBooleanValidator booleanValidator = new HeatBooleanValidator();
+    private static HeatBooleanValidator booleanValidator = new HeatBooleanValidator();
 
-	public static HeatBooleanValidator getInstance() {
-		return booleanValidator;
-	}
+    public static HeatBooleanValidator getInstance() {
+        return booleanValidator;
+    }
 
-	private HeatBooleanValidator() {
+    private HeatBooleanValidator() {
 
-	}
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (value == null || true == value.isEmpty()) {
-			return true;
-		}
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
 
-		if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false") || value.equalsIgnoreCase("t")
-				|| value.equalsIgnoreCase("f") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("off")
-				|| value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("y")
-				|| value.equalsIgnoreCase("n") || value.equalsIgnoreCase("1") || value.equalsIgnoreCase("0")) {
-			return true;
-		}
+        if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false") || value.equalsIgnoreCase("t")
+                || value.equalsIgnoreCase("f") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("off")
+                || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("y")
+                || value.equalsIgnoreCase("n") || value.equalsIgnoreCase("1") || value.equalsIgnoreCase("0")) {
+            return true;
+        }
 
-		return false;
-	}
+        return false;
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.java
index 464dbf0..6a2a134 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.java
@@ -20,36 +20,36 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.common.util.ValidationUtils;
 
+import java.util.Map;
+
 public class HeatCommaDelimitedListValidator implements PropertyTypeValidator {
 
-	private static HeatCommaDelimitedListValidator stringValidator = new HeatCommaDelimitedListValidator();
+    private static HeatCommaDelimitedListValidator stringValidator = new HeatCommaDelimitedListValidator();
 
-	public static HeatCommaDelimitedListValidator getInstance() {
-		return stringValidator;
-	}
+    public static HeatCommaDelimitedListValidator getInstance() {
+        return stringValidator;
+    }
 
-	private HeatCommaDelimitedListValidator() {
+    private HeatCommaDelimitedListValidator() {
 
-	}
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (value == null || true == value.isEmpty()) {
-			return true;
-		}
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
 
-		String coverted = ValidationUtils.removeNoneUtf8Chars(value);
-		return ValidationUtils.validateIsEnglish(coverted);
-	}
+        String coverted = ValidationUtils.removeNoneUtf8Chars(value);
+        return ValidationUtils.validateIsEnglish(coverted);
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.java
index 37c4a46..0ae3f74 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.java
@@ -20,42 +20,42 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class HeatNumberValidator implements PropertyTypeValidator {
 
-	private static HeatNumberValidator numberValidator = new HeatNumberValidator();
+    private static HeatNumberValidator numberValidator = new HeatNumberValidator();
 
-	private static FloatValidator floatValidator = FloatValidator.getInstance();
-	private static IntegerValidator integerValidator = IntegerValidator.getInstance();
+    private static FloatValidator floatValidator = FloatValidator.getInstance();
+    private static IntegerValidator integerValidator = IntegerValidator.getInstance();
 
-	public static HeatNumberValidator getInstance() {
-		return numberValidator;
-	}
+    public static HeatNumberValidator getInstance() {
+        return numberValidator;
+    }
 
-	private HeatNumberValidator() {
+    private HeatNumberValidator() {
 
-	}
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (value == null || true == value.isEmpty()) {
-			return true;
-		}
-		boolean valid = integerValidator.isValid(value, null, allDataTypes);
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
+        boolean valid = integerValidator.isValid(value, null, allDataTypes);
 
-		if (!valid) {
-			valid = floatValidator.isValid(value, null, allDataTypes);
-		}
+        if (!valid) {
+            valid = floatValidator.isValid(value, null, allDataTypes);
+        }
 
-		return valid;
-	}
+        return valid;
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.java
index 8c63090..fd71647 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.java
@@ -20,36 +20,36 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.common.util.ValidationUtils;
 
+import java.util.Map;
+
 public class HeatStringValidator implements PropertyTypeValidator {
 
-	private static HeatStringValidator stringValidator = new HeatStringValidator();
+    private static HeatStringValidator stringValidator = new HeatStringValidator();
 
-	public static HeatStringValidator getInstance() {
-		return stringValidator;
-	}
+    public static HeatStringValidator getInstance() {
+        return stringValidator;
+    }
 
-	private HeatStringValidator() {
+    private HeatStringValidator() {
 
-	}
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (value == null || true == value.isEmpty()) {
-			return true;
-		}
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
 
-		String converted = ValidationUtils.removeNoneUtf8Chars(value);
-		return ValidationUtils.validateIsEnglish(converted);
-	}
+        String converted = ValidationUtils.removeNoneUtf8Chars(value);
+        return ValidationUtils.validateIsEnglish(converted);
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.java
index 61d321c..484f88e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.java
@@ -20,66 +20,66 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
 public class IntegerValidator implements PropertyTypeValidator {
 
-	private static IntegerValidator integerValidator = new IntegerValidator();
+    private static IntegerValidator integerValidator = new IntegerValidator();
 
-	private IntegerValidator() {
-	}
+    private IntegerValidator() {
+    }
 
-	public static IntegerValidator getInstance() {
-		return integerValidator;
-	}
+    public static IntegerValidator getInstance() {
+        return integerValidator;
+    }
 
-	private class PatternBase {
-		public PatternBase(Pattern pattern, Integer base) {
-			this.pattern = pattern;
-			this.base = base;
-		}
+    private class PatternBase {
+        public PatternBase(Pattern pattern, Integer base) {
+            this.pattern = pattern;
+            this.base = base;
+        }
 
-		Pattern pattern;
-		Integer base;
-	}
+        Pattern pattern;
+        Integer base;
+    }
 
-	private PatternBase base8Pattern = new PatternBase(Pattern.compile("([-+])?0o([0-7]+)"), 8);
-	private PatternBase base10Pattern = new PatternBase(Pattern.compile("([-+])?(0|[1-9][0-9]*)"), 10);
-	private PatternBase base16Pattern = new PatternBase(Pattern.compile("([-+])?0x([0-9a-fA-F]+)"), 16);
+    private PatternBase base8Pattern = new PatternBase(Pattern.compile("([-+])?0o([0-7]+)"), 8);
+    private PatternBase base10Pattern = new PatternBase(Pattern.compile("([-+])?(0|[1-9][0-9]*)"), 10);
+    private PatternBase base16Pattern = new PatternBase(Pattern.compile("([-+])?0x([0-9a-fA-F]+)"), 16);
 
-	private PatternBase[] patterns = { base10Pattern, base8Pattern, base16Pattern };
+    private PatternBase[] patterns = { base10Pattern, base8Pattern, base16Pattern };
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (value == null || true == value.isEmpty()) {
-			return true;
-		}
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
 
-		for (PatternBase patternBase : patterns) {
-			Matcher matcher = patternBase.pattern.matcher(value);
-			Long parsed = null;
-			if (matcher.matches()) {
-				try {
-					parsed = Long.parseLong(matcher.group(2), patternBase.base);
-					if (matcher.group(1) != null && matcher.group(1).compareTo("-") == 0) {
-						parsed *= -1;
-					}
-					return (Integer.MIN_VALUE <= parsed && parsed <= (Integer.MAX_VALUE)) ? true : false;
-				} catch (NumberFormatException e) {
-					return false;
-				}
-			}
-		}
-		return false;
-	}
+        for (PatternBase patternBase : patterns) {
+            Matcher matcher = patternBase.pattern.matcher(value);
+            Long parsed = null;
+            if (matcher.matches()) {
+                try {
+                    parsed = Long.parseLong(matcher.group(2), patternBase.base);
+                    if (matcher.group(1) != null && matcher.group(1).compareTo("-") == 0) {
+                        parsed *= -1;
+                    }
+                    return (Integer.MIN_VALUE <= parsed && parsed <= (Integer.MAX_VALUE)) ? true : false;
+                } catch (NumberFormatException e) {
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.java
index 6a1aff5..77fcf52 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.java
@@ -20,50 +20,48 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.io.StringReader;
-import java.util.Map;
-
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import com.google.gson.JsonParser;
 import com.google.gson.JsonSyntaxException;
 import com.google.gson.stream.JsonReader;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+import java.io.StringReader;
+import java.util.Map;
 
 public class JsonValidator implements PropertyTypeValidator {
 
-	private static JsonValidator jsonValidator = new JsonValidator();
+    private static JsonValidator jsonValidator = new JsonValidator();
 
-	private static Logger log = LoggerFactory.getLogger(JsonValidator.class.getName());
+    private static final Logger log = Logger.getLogger(JsonValidator.class.getName());
 
-	private static JsonParser jsonParser = new JsonParser();
+    private static JsonParser jsonParser = new JsonParser();
 
-	public static JsonValidator getInstance() {
-		return jsonValidator;
-	}
+    public static JsonValidator getInstance() {
+        return jsonValidator;
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (value == null || value.isEmpty()) {
-			return true;
-		}
-		try {
-			StringReader reader = new StringReader(value);
-			JsonReader jsonReader = new JsonReader(reader);
-			jsonReader.setLenient(true);
-			jsonParser.parse(jsonReader);
-		} catch (JsonSyntaxException e) {
-			log.debug("Error parsing JSON property", e);
-			return false;
-		}
-		return true;
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
+        try {
+            StringReader reader = new StringReader(value);
+            JsonReader jsonReader = new JsonReader(reader);
+            jsonReader.setLenient(true);
+            jsonParser.parse(jsonReader);
+        } catch (JsonSyntaxException e) {
+            log.debug("Error parsing JSON property", e);
+            return false;
+        }
+        return true;
 
-	}
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.java
index 73b5e93..07e1233 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.java
@@ -20,42 +20,42 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.common.util.ValidationUtils;
 
+import java.util.Map;
+
 public class KeyValidator implements PropertyTypeValidator {
 
-	public static final int STRING_MAXIMUM_LENGTH = 100;
+    public static final int STRING_MAXIMUM_LENGTH = 100;
 
-	private static KeyValidator keyValidator = new KeyValidator();
+    private static KeyValidator keyValidator = new KeyValidator();
 
-	public static KeyValidator getInstance() {
-		return keyValidator;
-	}
+    public static KeyValidator getInstance() {
+        return keyValidator;
+    }
 
-	private KeyValidator() {
+    private KeyValidator() {
 
-	}
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (value == null || true == value.isEmpty()) {
-			return false;
-		}
+        if (value == null || value.isEmpty()) {
+            return false;
+        }
 
-		if (value.length() > STRING_MAXIMUM_LENGTH) {
-			return false;
-		}
-		String converted = ValidationUtils.removeNoneUtf8Chars(value);
-		return ValidationUtils.validateIsEnglish(converted);
-	}
+        if (value.length() > STRING_MAXIMUM_LENGTH) {
+            return false;
+        }
+        String converted = ValidationUtils.removeNoneUtf8Chars(value);
+        return ValidationUtils.validateIsEnglish(converted);
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java
index 8eb7840..ed40964 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java
@@ -20,141 +20,138 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-
-import org.openecomp.sdc.be.config.BeEcompErrorManager;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
-import org.openecomp.sdc.common.util.JsonUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonParser;
-import com.google.gson.JsonSyntaxException;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.openecomp.sdc.common.util.JsonUtils;
+
+import java.util.Map;
 
 public class ListValidator implements PropertyTypeValidator {
 
-	private static ListValidator listValidator = new ListValidator();
+    private static ListValidator listValidator = new ListValidator();
 
-	private static Logger log = LoggerFactory.getLogger(ListValidator.class.getName());
+    private static final Logger log = Logger.getLogger(ListValidator.class.getName());
 
-	private static JsonParser jsonParser = new JsonParser();
+    private static JsonParser jsonParser = new JsonParser();
 
-	private static DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
+    private static DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
 
-	public static ListValidator getInstance() {
-		return listValidator;
-	}
+    public static ListValidator getInstance() {
+        return listValidator;
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		log.debug("Going to validate value {} with inner type {}", value, innerType);
+        log.debug("Going to validate value {} with inner type {}", value, innerType);
 
-		if (value == null || value == "") {
-			return true;
-		}
-		if (innerType == null) {
-			return false;
-		}
+        if (value == null || value == "") {
+            return true;
+        }
+        if (innerType == null) {
+            return false;
+        }
 
-		PropertyTypeValidator innerValidator;
+        PropertyTypeValidator innerValidator;
 
-		ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
+        ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
 
-		if (innerToscaType != null) {
-			switch (innerToscaType) {
-			case STRING:
-				innerValidator = ToscaPropertyType.STRING.getValidator();
-				break;
-			case INTEGER:
-				innerValidator = ToscaPropertyType.INTEGER.getValidator();
-				break;
-			case FLOAT:
-				innerValidator = ToscaPropertyType.FLOAT.getValidator();
-				break;
-			case BOOLEAN:
-				innerValidator = ToscaPropertyType.BOOLEAN.getValidator();
-				break;
-			case JSON:
-				innerValidator = ToscaPropertyType.JSON.getValidator();
-				break;
-			default:
-				log.debug("inner Tosca Type is unknown. {}", innerToscaType);
-				return false;
-			}
+        if (innerToscaType != null) {
+            switch (innerToscaType) {
+            case STRING:
+                innerValidator = ToscaPropertyType.STRING.getValidator();
+                break;
+            case INTEGER:
+                innerValidator = ToscaPropertyType.INTEGER.getValidator();
+                break;
+            case FLOAT:
+                innerValidator = ToscaPropertyType.FLOAT.getValidator();
+                break;
+            case BOOLEAN:
+                innerValidator = ToscaPropertyType.BOOLEAN.getValidator();
+                break;
+            case JSON:
+                innerValidator = ToscaPropertyType.JSON.getValidator();
+                break;
+            default:
+                log.debug("inner Tosca Type is unknown. {}", innerToscaType);
+                return false;
+            }
 
-		} else {
-			log.debug("inner Tosca Type is: {}", innerType);
+        } else {
+            log.debug("inner Tosca Type is: {}", innerType);
 
-			boolean isValid = validateComplexInnerType(value, innerType, allDataTypes);
-			log.debug("Finish to validate value {} of list with inner type {}. result is {}",value,innerType,isValid);
-			return isValid;
-		}
+            boolean isValid = validateComplexInnerType(value, innerType, allDataTypes);
+            log.debug("Finish to validate value {} of list with inner type {}. result is {}",value,innerType,isValid);
+            return isValid;
+        }
 
-		try {
-			JsonArray jo = (JsonArray) jsonParser.parse(value);
-			if(ToscaPropertyType.JSON == innerToscaType)
-				return true;
-			int size = jo.size();
-			for (int i = 0; i < size; i++) {
-				JsonElement currentValue = jo.get(i);
-				String element = JsonUtils.toString(currentValue);
-				if (!innerValidator.isValid(element, null, allDataTypes)) {
-					log.debug("validation of element : {} failed", element);
-					return false;
-				}
+        try {
+            JsonArray jo = (JsonArray) jsonParser.parse(value);
+            if(ToscaPropertyType.JSON == innerToscaType)
+                return true;
+            int size = jo.size();
+            for (int i = 0; i < size; i++) {
+                JsonElement currentValue = jo.get(i);
+                String element = JsonUtils.toString(currentValue);
+                if (!innerValidator.isValid(element, null, allDataTypes)) {
+                    log.debug("validation of element : {} failed", element);
+                    return false;
+                }
 
-			}
-			return true;
+            }
+            return true;
 
-		} catch (JsonSyntaxException e) {
-			log.debug("Failed to parse json : {}", value, e);
-			BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Validator");
-		}
+        } catch (Exception e) {
+            log.debug("Failed to parse json : {}", value, e);
+            BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Validator");
+        }
 
-		return false;
+        return false;
 
-	}
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 
-	private boolean validateComplexInnerType(String value, String innerType,
-			Map<String, DataTypeDefinition> allDataTypes) {
+    private boolean validateComplexInnerType(String value, String innerType,
+            Map<String, DataTypeDefinition> allDataTypes) {
 
-		DataTypeDefinition innerDataTypeDefinition = allDataTypes.get(innerType);
-		if (innerDataTypeDefinition == null) {
-			log.debug("Data type {} cannot be found in our data types.", innerType);
-			return false;
-		}
+        DataTypeDefinition innerDataTypeDefinition = allDataTypes.get(innerType);
+        if (innerDataTypeDefinition == null) {
+            log.debug("Data type {} cannot be found in our data types.", innerType);
+            return false;
+        }
 
-		try {
+        try {
 
-			JsonArray jo = (JsonArray) jsonParser.parse(value);
-			int size = jo.size();
-			for (int i = 0; i < size; i++) {
-				JsonElement currentValue = jo.get(i);
-				if (currentValue != null) {
-					String element = JsonUtils.toString(currentValue);
-					boolean isValid = dataTypeValidatorConverter.isValid(element, innerDataTypeDefinition,
-							allDataTypes);
-					if (isValid == false) {
-						log.debug("Cannot parse value {} from type {} in list parameter",currentValue,innerType);
-						return false;
-					}
-				}
-			}
+            JsonArray jo = (JsonArray) jsonParser.parse(value);
+            int size = jo.size();
+            for (int i = 0; i < size; i++) {
+                JsonElement currentValue = jo.get(i);
+                if (currentValue != null) {
+                    String element = JsonUtils.toString(currentValue);
+                    boolean isValid = dataTypeValidatorConverter.isValid(element, innerDataTypeDefinition,
+                            allDataTypes);
+                    if (!isValid) {
+                        log.debug("Cannot parse value {} from type {} in list parameter",currentValue,innerType);
+                        return false;
+                    }
+                }
+            }
 
-		} catch (Exception e) {
-			log.debug("Error when parsing JSON of object of type ", e);
-			return false;
-		}
+        } catch (Exception e) {
+            log.debug("Error when parsing JSON of object of type ", e);
+            return false;
+        }
 
-		return true;
-	}
+        return true;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java
index 862766b..996e24e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java
@@ -20,22 +20,20 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.commons.lang.StringUtils;
-import org.openecomp.sdc.be.config.BeEcompErrorManager;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
-import org.openecomp.sdc.common.util.JsonUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
 import com.google.gson.JsonSyntaxException;
+import org.apache.commons.lang.StringUtils;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.openecomp.sdc.common.util.JsonUtils;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
 
 /*
  * Property Type Map correct usage:
@@ -47,90 +45,90 @@
 
 Types:
 when written line by line :
-					key1 : val1
-					key2 : val2
+                    key1 : val1
+                    key2 : val2
 key1 and val does not need "    " , even if val1 is a string.
 when written as one line : {"key1":val1 , "key2":val2}
 Keys always need " " around them.
 */
 public class MapValidator implements PropertyTypeValidator {
 
-	private static MapValidator mapValidator = new MapValidator();
+    private static MapValidator mapValidator = new MapValidator();
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(MapValidator.class.getName());
+    private static final Logger log = Logger.getLogger(MapValidator.class.getName());
 
-	private static DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
+    private static DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
 
-	private static JsonParser jsonParser = new JsonParser();
+    private static JsonParser jsonParser = new JsonParser();
 
-	public static MapValidator getInstance() {
-		return mapValidator;
-	}
+    public static MapValidator getInstance() {
+        return mapValidator;
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (StringUtils.isEmpty(value)) {
-			return true;
-		}
-		if (innerType == null) {
-			return false;
-		}
+        if (StringUtils.isEmpty(value)) {
+            return true;
+        }
+        if (innerType == null) {
+            return false;
+        }
 
-		PropertyTypeValidator innerValidator;
-		PropertyTypeValidator keyValidator = ToscaPropertyType.KEY.getValidator();
-		ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
+        PropertyTypeValidator innerValidator;
+        PropertyTypeValidator keyValidator = ToscaPropertyType.KEY.getValidator();
+        ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
 
-		if (innerToscaType != null) {
-			switch (innerToscaType) {
-			case STRING:
-				innerValidator = ToscaPropertyType.STRING.getValidator();
-				break;
-			case INTEGER:
-				innerValidator = ToscaPropertyType.INTEGER.getValidator();
-				break;
-			case FLOAT:
-				innerValidator = ToscaPropertyType.FLOAT.getValidator();
-				break;
-			case BOOLEAN:
-				innerValidator = ToscaPropertyType.BOOLEAN.getValidator();
-				break;
-			case JSON:
-				innerValidator = ToscaPropertyType.JSON.getValidator();
-				break;
-			default:
-				LOGGER.debug("inner Tosca Type is unknown. {}", innerToscaType);
-				return false;
-			}
-
-		} else {
-			LOGGER.debug("inner Tosca Type is: {}", innerType);
-
-			boolean isValid = validateComplexInnerType(value, innerType, allDataTypes);
-			LOGGER.debug("Finish to validate value {} of map with inner type {}. result is {}",value,innerType,isValid);
-			return isValid;
-
-		}
-
-		try {
-			JsonElement jsonObject = jsonParser.parse(value);
-			if (!jsonObject.isJsonObject()) {
-			    return false;
+        if (innerToscaType != null) {
+            switch (innerToscaType) {
+            case STRING:
+                innerValidator = ToscaPropertyType.STRING.getValidator();
+                break;
+            case INTEGER:
+                innerValidator = ToscaPropertyType.INTEGER.getValidator();
+                break;
+            case FLOAT:
+                innerValidator = ToscaPropertyType.FLOAT.getValidator();
+                break;
+            case BOOLEAN:
+                innerValidator = ToscaPropertyType.BOOLEAN.getValidator();
+                break;
+            case JSON:
+                innerValidator = ToscaPropertyType.JSON.getValidator();
+                break;
+            default:
+                log.debug("inner Tosca Type is unknown. {}", innerToscaType);
+                return false;
             }
-			JsonObject valueAsJson = jsonObject.getAsJsonObject();
-			return validateJsonObject(allDataTypes, innerValidator, keyValidator, valueAsJson);
-		} catch (JsonSyntaxException e) {
-			LOGGER.debug("Failed to parse json : {}", value, e);
-			BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Map Validator");
-		}
 
-		return false;
+        } else {
+            log.debug("inner Tosca Type is: {}", innerType);
 
-	}
+            boolean isValid = validateComplexInnerType(value, innerType, allDataTypes);
+            log.debug("Finish to validate value {} of map with inner type {}. result is {}",value,innerType,isValid);
+            return isValid;
 
-	private boolean validateJsonObject(Map<String, DataTypeDefinition> allDataTypes, PropertyTypeValidator innerValidator, PropertyTypeValidator keyValidator, JsonObject asJsonObject) {
-		Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
-		for (Entry<String, JsonElement> entry : entrySet) {
+        }
+
+        try {
+            JsonElement jsonObject = jsonParser.parse(value);
+            if (!jsonObject.isJsonObject()) {
+                return false;
+            }
+            JsonObject valueAsJson = jsonObject.getAsJsonObject();
+            return validateJsonObject(allDataTypes, innerValidator, keyValidator, valueAsJson);
+        } catch (JsonSyntaxException e) {
+            log.debug("Failed to parse json : {}", value, e);
+            BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Map Validator");
+        }
+
+        return false;
+
+    }
+
+    private boolean validateJsonObject(Map<String, DataTypeDefinition> allDataTypes, PropertyTypeValidator innerValidator, PropertyTypeValidator keyValidator, JsonObject asJsonObject) {
+        Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
+        for (Entry<String, JsonElement> entry : entrySet) {
             String currentKey = entry.getKey();
             JsonElement jsonValue = entry.getValue();
 
@@ -138,52 +136,52 @@
 
             if (!innerValidator.isValid(element, null, allDataTypes)
                     || !keyValidator.isValid(entry.getKey(), null, allDataTypes)) {
-                LOGGER.debug("validation of key : {}, element : {} failed", currentKey, entry.getValue());
+                log.debug("validation of key : {}, element : {} failed", currentKey, entry.getValue());
                 return false;
             }
         }
 
-		return true;
-	}
+        return true;
+    }
 
-	private boolean validateComplexInnerType(String value, String innerType,
-			Map<String, DataTypeDefinition> allDataTypes) {
+    private boolean validateComplexInnerType(String value, String innerType,
+            Map<String, DataTypeDefinition> allDataTypes) {
 
-		DataTypeDefinition innerDataTypeDefinition = allDataTypes.get(innerType);
-		if (innerDataTypeDefinition == null) {
-			LOGGER.debug("Data type {} cannot be found in our data types.", innerType);
-			return false;
-		}
+        DataTypeDefinition innerDataTypeDefinition = allDataTypes.get(innerType);
+        if (innerDataTypeDefinition == null) {
+            log.debug("Data type {} cannot be found in our data types.", innerType);
+            return false;
+        }
 
-		try {
-			JsonElement jsonObject = jsonParser.parse(value);
-			JsonObject asJsonObject = jsonObject.getAsJsonObject();
-			Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
-			for (Entry<String, JsonElement> entry : entrySet) {
-				String currentKey = entry.getKey();
-				JsonElement currentValue = entry.getValue();
+        try {
+            JsonElement jsonObject = jsonParser.parse(value);
+            JsonObject asJsonObject = jsonObject.getAsJsonObject();
+            Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
+            for (Entry<String, JsonElement> entry : entrySet) {
+                String currentKey = entry.getKey();
+                JsonElement currentValue = entry.getValue();
 
-				if (currentValue != null) {
-					String element = JsonUtils.toString(currentValue);
-					boolean isValid = dataTypeValidatorConverter.isValid(element, innerDataTypeDefinition,
-							allDataTypes);
-					if (!isValid) {
-						LOGGER.debug("Cannot parse value {} from type {} of key {}",currentValue,innerType,currentKey);
-						return false;
-					}
-				}
-			}
+                if (currentValue != null) {
+                    String element = JsonUtils.toString(currentValue);
+                    boolean isValid = dataTypeValidatorConverter.isValid(element, innerDataTypeDefinition,
+                            allDataTypes);
+                    if (!isValid) {
+                        log.debug("Cannot parse value {} from type {} of key {}",currentValue,innerType,currentKey);
+                        return false;
+                    }
+                }
+            }
 
-		} catch (Exception e) {
-			LOGGER.debug("Cannot parse value {} of map from inner type {}", value, innerType, e);
-			return false;
-		}
+        } catch (Exception e) {
+            log.debug("Cannot parse value {} of map from inner type {}", value, innerType, e);
+            return false;
+        }
 
-		return true;
-	}
+        return true;
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.java
index f0cf225..587107a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.java
@@ -20,27 +20,27 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public interface PropertyTypeValidator {
 
-	boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes);
+    boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes);
 
-	boolean isValid(String value, String innerType);
-	/*
-	 * The value format should be validated according to the "Property Type" :
-	 * "integer" - valid tag:yaml.org,2002:int , the number base 8,10,18 should
-	 * be handled ( hint : to validate by calling parseInt(
-	 * s,10)/parseInt(s,16)/parseInt(s,8) or just regexp [-+]?[0-9]+ for Base 10
-	 * , [-+]?0[0-7]+ for Base 8 , [-+]?0x[0-9a-fA-F]+ for Base 16
-	 * 
-	 * "float" - valid tag:yaml.org,2002:float , parseFloat() "boolean" - valid
-	 * tag:yaml.org,2002:bool : can be only "true" or "false" ( upper case
-	 * characters should be converted to lower case : TRUE ->true, True->true
-	 * "string" - valid tag:yaml.org,2002:str and limited to 100 chars.
-	 * 
-	 */
+    boolean isValid(String value, String innerType);
+    /*
+     * The value format should be validated according to the "Property Type" :
+     * "integer" - valid tag:yaml.org,2002:int , the number base 8,10,18 should
+     * be handled ( hint : to validate by calling parseInt(
+     * s,10)/parseInt(s,16)/parseInt(s,8) or just regexp [-+]?[0-9]+ for Base 10
+     * , [-+]?0[0-7]+ for Base 8 , [-+]?0x[0-9a-fA-F]+ for Base 16
+     *
+     * "float" - valid tag:yaml.org,2002:float , parseFloat() "boolean" - valid
+     * tag:yaml.org,2002:bool : can be only "true" or "false" ( upper case
+     * characters should be converted to lower case : TRUE ->true, True->true
+     * "string" - valid tag:yaml.org,2002:str and limited to 100 chars.
+     *
+     */
 
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.java
index dad3461..cd8d927 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.java
@@ -20,66 +20,65 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.config.Configuration.ToscaValidatorsConfig;
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import java.util.Map;
 
 public class StringValidator implements PropertyTypeValidator {
 
-	public static final int DEFAULT_STRING_MAXIMUM_LENGTH = 2500;
+    public static final int DEFAULT_STRING_MAXIMUM_LENGTH = 2500;
 
-	private static int STRING_MAXIMUM_LENGTH = DEFAULT_STRING_MAXIMUM_LENGTH;
+    private static int STRING_MAXIMUM_LENGTH = DEFAULT_STRING_MAXIMUM_LENGTH;
 
-	private static Logger log = LoggerFactory.getLogger(StringValidator.class.getName());
+    private static final Logger log = Logger.getLogger(StringValidator.class.getName());
 
-	private static StringValidator stringValidator = new StringValidator();
+    private static StringValidator stringValidator = new StringValidator();
 
-	private StringValidator() {
-		if (ConfigurationManager.getConfigurationManager() != null) {
-			ToscaValidatorsConfig toscaValidators = ConfigurationManager.getConfigurationManager().getConfiguration()
-					.getToscaValidators();
-			log.debug("toscaValidators= {}", toscaValidators);
-			if (toscaValidators != null) {
-				Integer stringMaxLength = toscaValidators.getStringMaxLength();
-				if (stringMaxLength != null) {
-					STRING_MAXIMUM_LENGTH = stringMaxLength;
-				}
-			}
-		}
-	}
+    private StringValidator() {
+        if (ConfigurationManager.getConfigurationManager() != null) {
+            ToscaValidatorsConfig toscaValidators = ConfigurationManager.getConfigurationManager().getConfiguration()
+                    .getToscaValidators();
+            log.debug("toscaValidators= {}", toscaValidators);
+            if (toscaValidators != null) {
+                Integer stringMaxLength = toscaValidators.getStringMaxLength();
+                if (stringMaxLength != null) {
+                    STRING_MAXIMUM_LENGTH = stringMaxLength;
+                }
+            }
+        }
+    }
 
-	public static StringValidator getInstance() {
-		return stringValidator;
-	}
+    public static StringValidator getInstance() {
+        return stringValidator;
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
 
-		if (value == null || true == value.isEmpty()) {
-			return true;
-		}
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
 
-		if (value.length() > STRING_MAXIMUM_LENGTH) {
-			log.debug("parameter String length {} is higher than configured({})", value.length(), STRING_MAXIMUM_LENGTH);
-			return false;
-		}
-		String converted = ValidationUtils.removeNoneUtf8Chars(value);
-		boolean isValid = ValidationUtils.validateIsAscii(converted);
+        if (value.length() > STRING_MAXIMUM_LENGTH) {
+            log.debug("parameter String length {} is higher than configured({})", value.length(), STRING_MAXIMUM_LENGTH);
+            return false;
+        }
+        String converted = ValidationUtils.removeNoneUtf8Chars(value);
+        boolean isValid = ValidationUtils.validateIsAscii(converted);
 
-		if (false == isValid && log.isDebugEnabled()) {
-			log.debug("parameter String value {} is not an ascii string.", value.substring(0, Math.min(value.length(), 20)));
-		}
+        if (!isValid && log.isDebugEnabled()) {
+            log.debug("parameter String value {} is not an ascii string.", value.substring(0, Math.min(value.length(), 20)));
+        }
 
-		return isValid;
-	}
+        return isValid;
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.java
index 7f8dff4..fbec8e8 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.java
@@ -20,37 +20,37 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+
 import java.util.Arrays;
 import java.util.Map;
 
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
 public class ToscaBooleanValidator implements PropertyTypeValidator {
 
-	private static ToscaBooleanValidator booleanValidator = new ToscaBooleanValidator();
+    private static ToscaBooleanValidator booleanValidator = new ToscaBooleanValidator();
 
-	private static String[] validValues = { "true", "on", "yes", "y", "false", "off", "no", "n" };
+    private static String[] validValues = { "true", "on", "yes", "y", "false", "off", "no", "n" };
 
-	public static ToscaBooleanValidator getInstance() {
-		return booleanValidator;
-	}
+    public static ToscaBooleanValidator getInstance() {
+        return booleanValidator;
+    }
 
-	private ToscaBooleanValidator() {
+    private ToscaBooleanValidator() {
 
-	}
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+    @Override
+    public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
 
-		if (value == null || true == value.isEmpty()) {
-			return true;
-		}
+        if (value == null || value.isEmpty()) {
+            return true;
+        }
 
-		return (Arrays.stream(validValues).filter(str -> str.equalsIgnoreCase(value)).toArray().length == 1);
-	}
+        return (Arrays.stream(validValues).filter(str -> str.equalsIgnoreCase(value)).toArray().length == 1);
+    }
 
-	@Override
-	public boolean isValid(String value, String innerType) {
-		return isValid(value, innerType, null);
-	}
+    @Override
+    public boolean isValid(String value, String innerType) {
+        return isValid(value, innerType, null);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.java
index dadfd49..9dca038 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.java
@@ -24,13 +24,11 @@
 
 public class ApplicationVersionException extends TechnicalException {
 
-	private static final long serialVersionUID = -5192834855057177252L;
+    public ApplicationVersionException(String message, Throwable cause) {
+        super(message, cause);
+    }
 
-	public ApplicationVersionException(String message, Throwable cause) {
-		super(message, cause);
-	}
-
-	public ApplicationVersionException(String message) {
-		super(message);
-	}
+    public ApplicationVersionException(String message) {
+        super(message);
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java
index 905d8bf..e3d8cf0 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java
@@ -40,14 +40,7 @@
  */
 
 import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Locale;
-import java.util.Properties;
-import java.util.Stack;
+import java.util.*;
 
 /**
  * Generic implementation of version comparison.
@@ -87,377 +80,374 @@
  * @author <a href="mailto:hboutemy@apache.org">Hervé Boutemy</a>
  */
 public class ComparableVersion implements Comparable<ComparableVersion> {
-	private String value;
+    private String value;
 
-	private String canonical;
+    private String canonical;
 
-	private ListItem items;
+    private ListItem items;
 
-	private interface Item {
-		int INTEGER_ITEM = 0;
-		int STRING_ITEM = 1;
-		int LIST_ITEM = 2;
+    private interface Item {
+        int INTEGER_ITEM = 0;
+        int STRING_ITEM = 1;
+        int LIST_ITEM = 2;
 
-		int compareTo(Item item);
+        int compareTo(Item item);
 
-		int getType();
+        int getType();
 
-		boolean isNull();
-	}
+        boolean isNull();
+    }
 
-	/**
-	 * Represents a numeric item in the version item list.
-	 */
-	private static class IntegerItem implements Item {
+    /**
+     * Represents a numeric item in the version item list.
+     */
+    private static class IntegerItem implements Item {
+        private static final String INVALID_ITEM = "invalid item: ";
 		private static final BigInteger BIG_INTEGER_ZERO = new BigInteger("0");
+        private final BigInteger value;
+        public static final IntegerItem ZERO = new IntegerItem();
 
-		private final BigInteger value;
+        private IntegerItem() {
+            this.value = BIG_INTEGER_ZERO;
+        }
 
-		public static final IntegerItem ZERO = new IntegerItem();
+        public IntegerItem(String str) {
+            this.value = new BigInteger(str);
+        }
 
-		private IntegerItem() {
-			this.value = BIG_INTEGER_ZERO;
-		}
+        @Override
+        public int getType() {
+            return INTEGER_ITEM;
+        }
 
-		public IntegerItem(String str) {
-			this.value = new BigInteger(str);
-		}
+        @Override
+        public boolean isNull() {
+            return BIG_INTEGER_ZERO.equals(value);
+        }
 
-		@Override
-		public int getType() {
-			return INTEGER_ITEM;
-		}
+        @Override
+        public int compareTo(Item item) {
+            if (item == null) {
+                return BIG_INTEGER_ZERO.equals(value) ? 0 : 1; // 1.0 == 1, 1.1
+                                                                // > 1
+            }
 
-		@Override
-		public boolean isNull() {
-			return BIG_INTEGER_ZERO.equals(value);
-		}
+            switch (item.getType()) {
+            case INTEGER_ITEM:
+                return value.compareTo(((IntegerItem) item).value);
 
-		@Override
-		public int compareTo(Item item) {
-			if (item == null) {
-				return BIG_INTEGER_ZERO.equals(value) ? 0 : 1; // 1.0 == 1, 1.1
-																// > 1
-			}
+            case STRING_ITEM:
+                return 1; // 1.1 > 1-sp
 
-			switch (item.getType()) {
-			case INTEGER_ITEM:
-				return value.compareTo(((IntegerItem) item).value);
+            case LIST_ITEM:
+                return 1; // 1.1 > 1-1
 
-			case STRING_ITEM:
-				return 1; // 1.1 > 1-sp
+            default:
+                throw new RuntimeException(INVALID_ITEM + item.getClass());
+            }
+        }
 
-			case LIST_ITEM:
-				return 1; // 1.1 > 1-1
+        @Override
+        public String toString() {
+            return value.toString();
+        }
+    }
 
-			default:
-				throw new RuntimeException("invalid item: " + item.getClass());
-			}
-		}
+    /**
+     * Represents a string in the version item list, usually a qualifier.
+     */
+    private static class StringItem implements Item {
+        private static final String[] QUALIFIERS = { "alpha", "beta", "milestone", "rc", "snapshot", "", "sp" };
 
-		@Override
-		public String toString() {
-			return value.toString();
-		}
-	}
+        private static final List<String> _QUALIFIERS = Arrays.asList(QUALIFIERS);
 
-	/**
-	 * Represents a string in the version item list, usually a qualifier.
-	 */
-	private static class StringItem implements Item {
-		private static final String[] QUALIFIERS = { "alpha", "beta", "milestone", "rc", "snapshot", "", "sp" };
+        private static final Properties ALIASES = new Properties();
+        static {
+            ALIASES.put("ga", "");
+            ALIASES.put("final", "");
+            ALIASES.put("cr", "rc");
+        }
 
-		private static final List<String> _QUALIFIERS = Arrays.asList(QUALIFIERS);
+        /**
+         * A comparable value for the empty-string qualifier. This one is used
+         * to determine if a given qualifier makes the version older than one
+         * without a qualifier, or more recent.
+         */
+        private static final String RELEASE_VERSION_INDEX = String.valueOf(_QUALIFIERS.indexOf(""));
 
-		private static final Properties ALIASES = new Properties();
-		static {
-			ALIASES.put("ga", "");
-			ALIASES.put("final", "");
-			ALIASES.put("cr", "rc");
-		}
+        private String value;
 
-		/**
-		 * A comparable value for the empty-string qualifier. This one is used
-		 * to determine if a given qualifier makes the version older than one
-		 * without a qualifier, or more recent.
-		 */
-		private static final String RELEASE_VERSION_INDEX = String.valueOf(_QUALIFIERS.indexOf(""));
+        public StringItem(String value, boolean followedByDigit) {
+            if (followedByDigit && value.length() == 1) {
+                // a1 = alpha-1, b1 = beta-1, m1 = milestone-1
+                switch (value.charAt(0)) {
+                case 'a':
+                    value = "alpha";
+                    break;
+                case 'b':
+                    value = "beta";
+                    break;
+                case 'm':
+                    value = "milestone";
+                    break;
+                }
+            }
+            this.value = ALIASES.getProperty(value, value);
+        }
 
-		private String value;
+        @Override
+        public int getType() {
+            return STRING_ITEM;
+        }
 
-		public StringItem(String value, boolean followedByDigit) {
-			if (followedByDigit && value.length() == 1) {
-				// a1 = alpha-1, b1 = beta-1, m1 = milestone-1
-				switch (value.charAt(0)) {
-				case 'a':
-					value = "alpha";
-					break;
-				case 'b':
-					value = "beta";
-					break;
-				case 'm':
-					value = "milestone";
-					break;
-				}
-			}
-			this.value = ALIASES.getProperty(value, value);
-		}
+        @Override
+        public boolean isNull() {
+            return (comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX) == 0);
+        }
 
-		@Override
-		public int getType() {
-			return STRING_ITEM;
-		}
+        /**
+         * Returns a comparable value for a qualifier.
+         *
+         * This method takes into account the ordering of known qualifiers then
+         * unknown qualifiers with lexical ordering.
+         *
+         * just returning an Integer with the index here is faster, but requires
+         * a lot of if/then/else to check for -1 or QUALIFIERS.size and then
+         * resort to lexical ordering. Most comparisons are decided by the first
+         * character, so this is still fast. If more characters are needed then
+         * it requires a lexical sort anyway.
+         *
+         * @param qualifier
+         * @return an equivalent value that can be used with lexical comparison
+         */
+        public static String comparableQualifier(String qualifier) {
+            int i = _QUALIFIERS.indexOf(qualifier);
 
-		@Override
-		public boolean isNull() {
-			return (comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX) == 0);
-		}
+            return i == -1 ? (_QUALIFIERS.size() + "-" + qualifier) : String.valueOf(i);
+        }
 
-		/**
-		 * Returns a comparable value for a qualifier.
-		 * 
-		 * This method takes into account the ordering of known qualifiers then
-		 * unknown qualifiers with lexical ordering.
-		 * 
-		 * just returning an Integer with the index here is faster, but requires
-		 * a lot of if/then/else to check for -1 or QUALIFIERS.size and then
-		 * resort to lexical ordering. Most comparisons are decided by the first
-		 * character, so this is still fast. If more characters are needed then
-		 * it requires a lexical sort anyway.
-		 * 
-		 * @param qualifier
-		 * @return an equivalent value that can be used with lexical comparison
-		 */
-		public static String comparableQualifier(String qualifier) {
-			int i = _QUALIFIERS.indexOf(qualifier);
+        // @Override
+        public int compareTo(Item item) {
+            if (item == null) {
+                // 1-rc < 1, 1-ga > 1
+                return comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX);
+            }
+            switch (item.getType()) {
+            case INTEGER_ITEM:
+                return -1; // 1.any < 1.1 ?
 
-			return i == -1 ? (_QUALIFIERS.size() + "-" + qualifier) : String.valueOf(i);
-		}
+            case STRING_ITEM:
+                return comparableQualifier(value).compareTo(comparableQualifier(((StringItem) item).value));
 
-		// @Override
-		public int compareTo(Item item) {
-			if (item == null) {
-				// 1-rc < 1, 1-ga > 1
-				return comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX);
-			}
-			switch (item.getType()) {
-			case INTEGER_ITEM:
-				return -1; // 1.any < 1.1 ?
+            case LIST_ITEM:
+                return -1; // 1.any < 1-1
 
-			case STRING_ITEM:
-				return comparableQualifier(value).compareTo(comparableQualifier(((StringItem) item).value));
+            default:
+                throw new RuntimeException("invalid item: " + item.getClass());
+            }
+        }
 
-			case LIST_ITEM:
-				return -1; // 1.any < 1-1
+        @Override
+        public String toString() {
+            return value;
+        }
+    }
 
-			default:
-				throw new RuntimeException("invalid item: " + item.getClass());
-			}
-		}
+    /**
+     * Represents a version list item. This class is used both for the global
+     * item list and for sub-lists (which start with '-(number)' in the version
+     * specification).
+     */
+    private static class ListItem extends ArrayList<Item> implements Item {
 
-		@Override
-		public String toString() {
-			return value;
-		}
-	}
+        @Override
+        public int getType() {
+            return LIST_ITEM;
+        }
 
-	/**
-	 * Represents a version list item. This class is used both for the global
-	 * item list and for sub-lists (which start with '-(number)' in the version
-	 * specification).
-	 */
-	private static class ListItem extends ArrayList<Item> implements Item {
+        @Override
+        public boolean isNull() {
+            return (size() == 0);
+        }
 
-		private static final long serialVersionUID = -4740226741001149657L;
+        void normalize() {
+            for (ListIterator<Item> iterator = listIterator(size()); iterator.hasPrevious();) {
+                Item item = iterator.previous();
+                if (item.isNull()) {
+                    iterator.remove(); // remove null trailing items: 0, "",
+                                        // empty list
+                } else {
+                    break;
+                }
+            }
+        }
 
-		@Override
-		public int getType() {
-			return LIST_ITEM;
-		}
-
-		@Override
-		public boolean isNull() {
-			return (size() == 0);
-		}
-
-		void normalize() {
-			for (ListIterator<Item> iterator = listIterator(size()); iterator.hasPrevious();) {
-				Item item = iterator.previous();
-				if (item.isNull()) {
-					iterator.remove(); // remove null trailing items: 0, "",
-										// empty list
-				} else {
-					break;
-				}
-			}
-		}
-
-		@Override
-		public int compareTo(Item item) {
-			if (item == null) {
-				if (size() == 0) {
-					return 0; // 1-0 = 1- (normalize) = 1
-				}
-				Item first = get(0);
-				return first.compareTo(null);
-			}
-			switch (item.getType()) {
-			case INTEGER_ITEM:
-				return -1; // 1-1 < 1.0.x
+        @Override
+        public int compareTo(Item item) {
+            if (item == null) {
+                if (size() == 0) {
+                    return 0; // 1-0 = 1- (normalize) = 1
+                }
+                Item first = get(0);
+                return first.compareTo(null);
+            }
+            switch (item.getType()) {
+            case INTEGER_ITEM:
+                return -1; // 1-1 < 1.0.x
 
-			case STRING_ITEM:
-				return 1; // 1-1 > 1-sp
+            case STRING_ITEM:
+                return 1; // 1-1 > 1-sp
 
-			case LIST_ITEM:
-				Iterator<Item> left = iterator();
-				Iterator<Item> right = ((ListItem) item).iterator();
+            case LIST_ITEM:
+                Iterator<Item> left = iterator();
+                Iterator<Item> right = ((ListItem) item).iterator();
 
-				while (left.hasNext() || right.hasNext()) {
-					Item l = left.hasNext() ? left.next() : null;
-					Item r = right.hasNext() ? right.next() : null;
+                while (left.hasNext() || right.hasNext()) {
+                    Item l = left.hasNext() ? left.next() : null;
+                    Item r = right.hasNext() ? right.next() : null;
 
-					int result = 0;
-					if (r != null && l != null) {
-						result = l.compareTo(r);
-					} else if (r == null && l == null) {
-						result = 0;
-					} else if (l == null) {
-						result = -1;
-					} else {
-						result = 1;
-					}
+                    int result = 0;
+                    if (r != null && l != null) {
+                        result = l.compareTo(r);
+                    } else if (r == null && l == null) {
+                        result = 0;
+                    } else if (l == null) {
+                        result = -1;
+                    } else {
+                        result = 1;
+                    }
 
-					// if this is shorter, then invert the compare and mul with
-					// -1
-					// int result = (l == null ? (r == null ? 0 : -1 *
-					// r.compareTo(l)) : l.compareTo(r));
+                    // if this is shorter, then invert the compare and mul with
+                    // -1
+                    // int result = (l == null ? (r == null ? 0 : -1 *
+                    // r.compareTo(l)) : l.compareTo(r));
 
-					if (result != 0) {
-						return result;
-					}
-				}
+                    if (result != 0) {
+                        return result;
+                    }
+                }
 
-				return 0;
+                return 0;
 
-			default:
-				throw new RuntimeException("invalid item: " + item.getClass());
-			}
-		}
+            default:
+                throw new RuntimeException("invalid item: " + item.getClass());
+            }
+        }
 
-		@Override
-		public String toString() {
-			StringBuilder buffer = new StringBuilder("(");
-			for (Iterator<Item> iter = iterator(); iter.hasNext();) {
-				buffer.append(iter.next());
-				if (iter.hasNext()) {
-					buffer.append(',');
-				}
-			}
-			buffer.append(')');
-			return buffer.toString();
-		}
-	}
+        @Override
+        public String toString() {
+            StringBuilder buffer = new StringBuilder("(");
+            for (Iterator<Item> iter = iterator(); iter.hasNext();) {
+                buffer.append(iter.next());
+                if (iter.hasNext()) {
+                    buffer.append(',');
+                }
+            }
+            buffer.append(')');
+            return buffer.toString();
+        }
+    }
 
-	public ComparableVersion(String version) {
-		parseVersion(version);
-	}
+    public ComparableVersion(String version) {
+        parseVersion(version);
+    }
 
-	public final void parseVersion(String version) {
-		this.value = version;
+    public final void parseVersion(String version) {
+        this.value = version;
 
-		items = new ListItem();
+        items = new ListItem();
 
-		version = version.toLowerCase(Locale.ENGLISH);
+        version = version.toLowerCase(Locale.ENGLISH);
 
-		ListItem list = items;
+        ListItem list = items;
 
-		Stack<Item> stack = new Stack<Item>();
-		stack.push(list);
+        Stack<Item> stack = new Stack<>();
+        stack.push(list);
 
-		boolean isDigit = false;
+        boolean isDigit = false;
 
-		int startIndex = 0;
+        int startIndex = 0;
 
-		for (int i = 0; i < version.length(); i++) {
-			char c = version.charAt(i);
+        for (int i = 0; i < version.length(); i++) {
+            char c = version.charAt(i);
 
-			if (c == '.') {
-				if (i == startIndex) {
-					list.add(IntegerItem.ZERO);
-				} else {
-					list.add(parseItem(isDigit, version.substring(startIndex, i)));
-				}
-				startIndex = i + 1;
-			} else if (c == '-') {
-				if (i == startIndex) {
-					list.add(IntegerItem.ZERO);
-				} else {
-					list.add(parseItem(isDigit, version.substring(startIndex, i)));
-				}
-				startIndex = i + 1;
+            if (c == '.') {
+                if (i == startIndex) {
+                    list.add(IntegerItem.ZERO);
+                } else {
+                    list.add(parseItem(isDigit, version.substring(startIndex, i)));
+                }
+                startIndex = i + 1;
+            } else if (c == '-') {
+                if (i == startIndex) {
+                    list.add(IntegerItem.ZERO);
+                } else {
+                    list.add(parseItem(isDigit, version.substring(startIndex, i)));
+                }
+                startIndex = i + 1;
 
-				if (isDigit) {
-					list.normalize(); // 1.0-* = 1-*
+                if (isDigit) {
+                    list.normalize(); // 1.0-* = 1-*
 
-					if ((i + 1 < version.length()) && Character.isDigit(version.charAt(i + 1))) {
-						// new ListItem only if previous were digits and new
-						// char is a digit,
-						// ie need to differentiate only 1.1 from 1-1
-						list.add(list = new ListItem());
+                    if ((i + 1 < version.length()) && Character.isDigit(version.charAt(i + 1))) {
+                        // new ListItem only if previous were digits and new
+                        // char is a digit,
+                        // ie need to differentiate only 1.1 from 1-1
+                        list.add(list = new ListItem());
 
-						stack.push(list);
-					}
-				}
-			} else if (Character.isDigit(c)) {
-				if (!isDigit && i > startIndex) {
-					list.add(new StringItem(version.substring(startIndex, i), true));
-					startIndex = i;
-				}
+                        stack.push(list);
+                    }
+                }
+            } else if (Character.isDigit(c)) {
+                if (!isDigit && i > startIndex) {
+                    list.add(new StringItem(version.substring(startIndex, i), true));
+                    startIndex = i;
+                }
 
-				isDigit = true;
-			} else {
-				if (isDigit && i > startIndex) {
-					list.add(parseItem(true, version.substring(startIndex, i)));
-					startIndex = i;
-				}
+                isDigit = true;
+            } else {
+                if (isDigit && i > startIndex) {
+                    list.add(parseItem(true, version.substring(startIndex, i)));
+                    startIndex = i;
+                }
 
-				isDigit = false;
-			}
-		}
+                isDigit = false;
+            }
+        }
 
-		if (version.length() > startIndex) {
-			list.add(parseItem(isDigit, version.substring(startIndex)));
-		}
+        if (version.length() > startIndex) {
+            list.add(parseItem(isDigit, version.substring(startIndex)));
+        }
 
-		while (!stack.isEmpty()) {
-			list = (ListItem) stack.pop();
-			list.normalize();
-		}
+        while (!stack.isEmpty()) {
+            list = (ListItem) stack.pop();
+            list.normalize();
+        }
 
-		canonical = items.toString();
-	}
+        canonical = items.toString();
+    }
 
-	private static Item parseItem(boolean isDigit, String buf) {
-		return isDigit ? new IntegerItem(buf) : new StringItem(buf, false);
-	}
+    private static Item parseItem(boolean isDigit, String buf) {
+        return isDigit ? new IntegerItem(buf) : new StringItem(buf, false);
+    }
 
-	@Override
-	public int compareTo(ComparableVersion o) {
-		return items.compareTo(o.items);
-	}
+    @Override
+    public int compareTo(ComparableVersion o) {
+        return items.compareTo(o.items);
+    }
 
-	@Override
-	public String toString() {
-		return value;
-	}
+    @Override
+    public String toString() {
+        return value;
+    }
 
-	@Override
-	public boolean equals(Object o) {
-		return (o instanceof ComparableVersion) && canonical.equals(((ComparableVersion) o).canonical);
-	}
+    @Override
+    public boolean equals(Object o) {
+        return (o instanceof ComparableVersion) && canonical.equals(((ComparableVersion) o).canonical);
+    }
 
-	@Override
-	public int hashCode() {
-		return canonical.hashCode();
-	}
+    @Override
+    public int hashCode() {
+        return canonical.hashCode();
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java
index 268ee28..0b71f03 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java
@@ -48,145 +48,145 @@
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
  */
 public class Version implements Comparable<Version> {
-	private Integer majorVersion;
+    private Integer majorVersion;
 
-	private Integer minorVersion;
+    private Integer minorVersion;
 
-	private Integer incrementalVersion;
+    private Integer incrementalVersion;
 
-	private Integer buildNumber;
+    private Integer buildNumber;
 
-	private String qualifier;
+    private String qualifier;
 
-	private ComparableVersion comparable;
+    private ComparableVersion comparable;
 
-	public Version(String version) {
-		parseVersion(version);
-	}
+    public Version(String version) {
+        parseVersion(version);
+    }
 
-	@Override
-	public int hashCode() {
-		return 11 + comparable.hashCode();
-	}
+    @Override
+    public int hashCode() {
+        return 11 + comparable.hashCode();
+    }
 
-	@Override
-	public boolean equals(Object other) {
-		if (this == other) {
-			return true;
-		}
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
 
-		if (!(other instanceof Version)) {
-			return false;
-		}
+        if (!(other instanceof Version)) {
+            return false;
+        }
 
-		return compareTo((Version) other) == 0;
-	}
+        return compareTo((Version) other) == 0;
+    }
 
-	public int compareTo(Version otherVersion) {
-		return this.comparable.compareTo(otherVersion.comparable);
-	}
+    public int compareTo(Version otherVersion) {
+        return this.comparable.compareTo(otherVersion.comparable);
+    }
 
-	public int getMajorVersion() {
-		return majorVersion != null ? majorVersion : 0;
-	}
+    public int getMajorVersion() {
+        return majorVersion != null ? majorVersion : 0;
+    }
 
-	public int getMinorVersion() {
-		return minorVersion != null ? minorVersion : 0;
-	}
+    public int getMinorVersion() {
+        return minorVersion != null ? minorVersion : 0;
+    }
 
-	public int getIncrementalVersion() {
-		return incrementalVersion != null ? incrementalVersion : 0;
-	}
+    public int getIncrementalVersion() {
+        return incrementalVersion != null ? incrementalVersion : 0;
+    }
 
-	public int getBuildNumber() {
-		return buildNumber != null ? buildNumber : 0;
-	}
+    public int getBuildNumber() {
+        return buildNumber != null ? buildNumber : 0;
+    }
 
-	public String getQualifier() {
-		return qualifier;
-	}
+    public String getQualifier() {
+        return qualifier;
+    }
 
-	public final void parseVersion(String version) {
-		comparable = new ComparableVersion(version);
+    public final void parseVersion(String version) {
+        comparable = new ComparableVersion(version);
 
-		int index = version.indexOf("-");
+        int index = version.indexOf("-");
 
-		String part1;
-		String part2 = null;
+        String part1;
+        String part2 = null;
 
-		if (index < 0) {
-			part1 = version;
-		} else {
-			part1 = version.substring(0, index);
-			part2 = version.substring(index + 1);
-		}
+        if (index < 0) {
+            part1 = version;
+        } else {
+            part1 = version.substring(0, index);
+            part2 = version.substring(index + 1);
+        }
 
-		if (part2 != null) {
-			try {
-				if ((part2.length() == 1) || !part2.startsWith("0")) {
-					buildNumber = Integer.valueOf(part2);
-				} else {
-					qualifier = part2;
-				}
-			} catch (NumberFormatException e) {
-				qualifier = part2;
-			}
-		}
+        if (part2 != null) {
+            try {
+                if ((part2.length() == 1) || !part2.startsWith("0")) {
+                    buildNumber = Integer.valueOf(part2);
+                } else {
+                    qualifier = part2;
+                }
+            } catch (NumberFormatException e) {
+                qualifier = part2;
+            }
+        }
 
-		if ((!part1.contains(".")) && !part1.startsWith("0")) {
-			try {
-				majorVersion = Integer.valueOf(part1);
-			} catch (NumberFormatException e) {
-				// qualifier is the whole version, including "-"
-				qualifier = version;
-				buildNumber = null;
-			}
-		} else {
-			boolean fallback = false;
+        if ((!part1.contains(".")) && !part1.startsWith("0")) {
+            try {
+                majorVersion = Integer.valueOf(part1);
+            } catch (NumberFormatException e) {
+                // qualifier is the whole version, including "-"
+                qualifier = version;
+                buildNumber = null;
+            }
+        } else {
+            boolean fallback = false;
 
-			StringTokenizer tok = new StringTokenizer(part1, ".");
-			try {
-				majorVersion = getNextIntegerToken(tok);
-				if (tok.hasMoreTokens()) {
-					minorVersion = getNextIntegerToken(tok);
-				}
-				if (tok.hasMoreTokens()) {
-					incrementalVersion = getNextIntegerToken(tok);
-				}
-				if (tok.hasMoreTokens()) {
-					qualifier = tok.nextToken();
-					fallback = Pattern.compile("\\d+").matcher(qualifier).matches();
-				}
+            StringTokenizer tok = new StringTokenizer(part1, ".");
+            try {
+                majorVersion = getNextIntegerToken(tok);
+                if (tok.hasMoreTokens()) {
+                    minorVersion = getNextIntegerToken(tok);
+                }
+                if (tok.hasMoreTokens()) {
+                    incrementalVersion = getNextIntegerToken(tok);
+                }
+                if (tok.hasMoreTokens()) {
+                    qualifier = tok.nextToken();
+                    fallback = Pattern.compile("\\d+").matcher(qualifier).matches();
+                }
 
-				// string tokenzier won't detect these and ignores them
-				if (part1.contains("..") || part1.startsWith(".") || part1.endsWith(".")) {
-					fallback = true;
-				}
-			} catch (NumberFormatException e) {
-				fallback = true;
-			}
+                // string tokenzier won't detect these and ignores them
+                if (part1.contains("..") || part1.startsWith(".") || part1.endsWith(".")) {
+                    fallback = true;
+                }
+            } catch (NumberFormatException e) {
+                fallback = true;
+            }
 
-			if (fallback) {
-				// qualifier is the whole version, including "-"
-				qualifier = version;
-				majorVersion = null;
-				minorVersion = null;
-				incrementalVersion = null;
-				buildNumber = null;
-			}
-		}
-	}
+            if (fallback) {
+                // qualifier is the whole version, including "-"
+                qualifier = version;
+                majorVersion = null;
+                minorVersion = null;
+                incrementalVersion = null;
+                buildNumber = null;
+            }
+        }
+    }
 
-	private static Integer getNextIntegerToken(StringTokenizer tok) {
-		String s = tok.nextToken();
-		if ((s.length() > 1) && s.startsWith("0")) {
-			throw new NumberFormatException("Number part has a leading 0: '" + s + "'");
-		}
-		return Integer.valueOf(s);
-	}
+    private static Integer getNextIntegerToken(StringTokenizer tok) {
+        String s = tok.nextToken();
+        if ((s.length() > 1) && s.startsWith("0")) {
+            throw new NumberFormatException("Number part has a leading 0: '" + s + "'");
+        }
+        return Integer.valueOf(s);
+    }
 
-	@Override
-	public String toString() {
-		return comparable.toString();
-	}
+    @Override
+    public String toString() {
+        return comparable.toString();
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/ComponentUtilities.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/ComponentUtilities.java
new file mode 100644
index 0000000..a38e880
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/ComponentUtilities.java
@@ -0,0 +1,39 @@
+package org.openecomp.sdc.be.model.utils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.sdc.be.datatypes.elements.Annotation;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.ComponentInstance;
+import org.openecomp.sdc.be.model.InputDefinition;
+
+import java.util.List;
+import java.util.Optional;
+
+import static java.util.Collections.emptyList;
+
+public class ComponentUtilities {
+    private ComponentUtilities() {
+    }
+
+    public static Optional<String> getComponentInstanceNameByInstanceId(Component component, String id) {
+        return component.getComponentInstanceById(id)
+                .flatMap(instance -> component.getComponentInstanceByName(instance.getName()))
+                .map(ComponentInstance::getName);
+    }
+
+    public static List<Annotation> getInputAnnotations(Component component, String inputName) {
+        return getInputByName(component, inputName)
+                .map(InputDefinition::getAnnotations)
+                .orElse(emptyList());
+    }
+
+    private static Optional<InputDefinition> getInputByName(Component component, String inputName) {
+        return component.safeGetInputs().stream()
+                .filter(input -> input.getName().equals(inputName))
+                .findFirst();
+    }
+
+    public static boolean isNotUpdatedCapReqName(String prefix, String currName, String previousName) {
+        return StringUtils.isEmpty(previousName) || !currName.equals(prefix + previousName);
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/GroupUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/GroupUtils.java
new file mode 100644
index 0000000..de2e06b
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/GroupUtils.java
@@ -0,0 +1,10 @@
+package org.openecomp.sdc.be.model.utils;
+
+import org.openecomp.sdc.common.api.Constants;
+
+public class GroupUtils {
+
+	public static boolean isVfModule(String type) {
+		return type.equals(Constants.DEFAULT_GROUP_VF_MODULE);
+	}
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/TypeCompareUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/TypeCompareUtils.java
new file mode 100644
index 0000000..298cae0
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/TypeCompareUtils.java
@@ -0,0 +1,207 @@
+package org.openecomp.sdc.be.model.utils;
+
+import com.google.common.base.Strings;
+import fj.data.Either;
+import org.apache.commons.collections.SetUtils;
+import org.openecomp.sdc.be.dao.utils.MapUtil;
+import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import static org.springframework.util.CollectionUtils.isEmpty;
+
+
+/**
+ * Types comparison utils
+ * The class is required since origin class "equals" methods
+ * take in account fields that should be ignored during update of that types.
+ * @author dr2032
+ *
+ */
+public class TypeCompareUtils {
+
+    private TypeCompareUtils() {
+    }
+    
+    public static <R> Either<R, StorageOperationStatus> typeAlreadyExists() {
+        return Either.right(StorageOperationStatus.OK);
+    }
+
+    public static boolean isGroupTypesEquals(GroupTypeDefinition gt1, GroupTypeDefinition gt2) {
+        if (gt1 == gt2) {
+            return true;
+        }
+        if (gt1 == null || gt2 == null) {
+            return false;
+        }
+        
+        /*
+         * We compare here attributes, capabilities and not inherited properties of group types.
+         * So even if properties of group type parent were changed it will not effect on comparison of these group types.
+         */
+        return Objects.equals(gt1.getType(), gt2.getType()) &&
+                Objects.equals(gt1.getName(), gt2.getName()) &&
+                Objects.equals(gt1.getIcon(), gt2.getIcon()) &&
+                Objects.equals(gt1.getVersion(), gt2.getVersion()) &&
+                Objects.equals(gt1.getDerivedFrom(), gt2.getDerivedFrom()) &&
+                Objects.equals(gt1.getMembers(), gt2.getMembers()) &&
+                Objects.equals(gt1.getMetadata(), gt2.getMetadata()) &&
+                capabilitiesEqual(gt1.getCapabilities(), gt2.getCapabilities()) && 
+                propertiesEquals(collectNotInheritedProperties(gt1.getProperties(), gt1.getUniqueId()), 
+                                collectNotInheritedProperties(gt2.getProperties(), gt2.getUniqueId()));
+    }
+    
+    public static boolean isCapabilityTypesEquals(CapabilityTypeDefinition ct1, CapabilityTypeDefinition ct2) {
+        if (ct1 == ct2) {
+            return true;
+        }
+        
+        if (ct1 == null || ct2 == null) {
+            return false;
+        }
+        
+        return Objects.equals(ct1.getType(), ct2.getType()) &&
+               Objects.equals(ct1.getDerivedFrom(), ct2.getDerivedFrom()) &&
+               Objects.equals(ct1.getDescription(), ct2.getDescription()) &&
+               SetUtils.isEqualSet(ct1.getValidSourceTypes(), ct2.getValidSourceTypes()) &&
+               propertiesEquals(ct1.getProperties(), ct2.getProperties());
+    }
+    
+    private static boolean propertiesEquals(Map<String, PropertyDefinition> props1, Map<String, PropertyDefinition> props2) {
+        if (props1 == props2) {
+            return true;
+        }
+        
+        if (isEmpty(props1) && isEmpty(props2)) {
+            return true;
+        }
+        else if(props1 == null || props2 == null) {
+            return false;
+        }
+        else if(props1.size() != props2.size())
+        {
+            return false;
+        }
+
+        return props2.entrySet().stream()
+                                .allMatch(entry -> propertyEquals(props1.get(entry.getKey()), entry.getValue()));
+        
+    }
+    
+    public static boolean propertiesEquals(List<PropertyDefinition> props1, List<PropertyDefinition> props2) {
+        if (props1 == props2) {
+            return true;
+        }
+        
+        if (isEmpty(props1) && isEmpty(props2)) {
+            return true;
+        }
+        else if(props1 == null || props2 == null) {
+            return false;
+        }
+        else if(props1.size() != props2.size())
+        {
+            return false;
+        }
+        
+        Map<String, PropertyDefinition> pt1PropsByName = MapUtil.toMap(props1, PropertyDefinition::getName);
+        return props2.stream()
+                       .allMatch(pt2Prop -> propertyEquals(pt1PropsByName.get(pt2Prop.getName()), pt2Prop));
+    }
+
+    private static boolean propertyEquals(PropertyDefinition prop1, PropertyDefinition prop2) {
+        if (prop1 == prop2) {
+            return true;
+        }
+        if (prop1 == null || prop2 == null) {
+            return false;
+        }
+        return Objects.equals(prop1.getDefaultValue(), prop2.getDefaultValue()) &&
+                prop1.isDefinition() == prop2.isDefinition() &&
+                Objects.equals(prop1.getDescription(), prop2.getDescription()) &&
+                prop1.isPassword() == prop2.isPassword() &&
+                prop1.isRequired() == prop2.isRequired() &&
+                Objects.equals(prop1.getSchemaType(), prop2.getSchemaType()) &&
+                Objects.equals(prop1.getType(), prop2.getType());
+    }
+
+    private static boolean capabilitiesEqual(Map<String, CapabilityDefinition> caps1, Map<String, CapabilityDefinition>  caps2) { 
+        if (caps1 == caps2) {
+            return true;
+        }
+        
+        if (caps1 == null || caps2 == null) {
+            return false;
+        }
+        
+        if(caps1.size() != caps2.size()) {
+            return false;
+        }
+            
+        return caps2.entrySet().stream()
+                .allMatch(capEntry2 -> capabilityEquals(caps1.get(capEntry2.getKey()), capEntry2.getValue()));
+    }
+
+    public static boolean capabilityEquals(CapabilityDefinition capDef1, CapabilityDefinition capDef2) {
+        return Objects.equals(capDef1.getName(), capDef2.getName()) &&
+                Objects.equals(capDef1.getType(), capDef2.getType()) &&
+                Objects.equals(capDef1.getDescription(), capDef2.getDescription()) &&
+                propValuesEqual(capDef1.getProperties(), capDef2.getProperties());
+    }
+
+    private static boolean propValuesEqual(final List<ComponentInstanceProperty> props1, final List<ComponentInstanceProperty> props2) {
+        Map<String, String> propValues1 = toValueMap(props1);
+        Map<String, String> propValues2 = toValueMap(props2);
+        
+        return propValues1.equals(propValues2);
+    }
+
+    /**
+     * @param props
+     * @return
+     */
+    private static Map<String, String> toValueMap(final List<ComponentInstanceProperty> props) {
+        return props.stream()
+                    .filter(TypeCompareUtils::isCapabilityPropValue)
+                    .collect(Collectors.toMap(ComponentInstanceProperty::getName, p -> p.getValue() != null? p.getValue(): ""));
+    }
+    
+    /**
+     * Returns true if the property object was created from property value or false otherwise
+     * 
+     * We try to segregate original properties values from dummy ones created from relevant properties.
+     * Such dummy property value doesn't have their valueUniqueId but it has uniqueId taken from property.
+     *    
+     * @param property
+     * @return
+     */
+    private static boolean isCapabilityPropValue(ComponentInstanceProperty property) {
+        return property.getValueUniqueUid() != null || property.getUniqueId() == null;
+    }
+    
+    /**
+     * Collect properties of resource that belongs to it without taking in account properties inherited from resource parents.
+     */
+    private static List<PropertyDefinition> collectNotInheritedProperties(List<PropertyDefinition> properties, 
+                                                                          String resourceId) {
+        if (Strings.isNullOrEmpty(resourceId)) {
+            return properties;
+        }
+        
+        return properties.stream()
+                         .filter(prop-> !isInherited(prop, resourceId))
+                         .collect(Collectors.toList());
+    }
+    
+    
+    private static boolean isInherited(PropertyDefinition prop, String resourceId) {
+        return prop.getUniqueId() != null && 
+                !prop.getUniqueId().equals(UniqueIdBuilder.buildPropertyUniqueId(resourceId, prop.getName()));
+    }
+    
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiCategories.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiCategories.java
index cda23cb..8bbe02e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiCategories.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiCategories.java
@@ -20,32 +20,32 @@
 
 package org.openecomp.sdc.be.ui.model;
 
-import java.util.List;
-
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 
+import java.util.List;
+
 public class UiCategories {
-	
-	private List<CategoryDefinition> resourceCategories;
-	private List<CategoryDefinition> serviceCategories;
-	private List<CategoryDefinition> productCategories;
-	
-	public List<CategoryDefinition> getResourceCategories() {
-		return resourceCategories;
-	}
-	public void setResourceCategories(List<CategoryDefinition> resourceCategories) {
-		this.resourceCategories = resourceCategories;
-	}
-	public List<CategoryDefinition> getServiceCategories() {
-		return serviceCategories;
-	}
-	public void setServiceCategories(List<CategoryDefinition> serviceCategories) {
-		this.serviceCategories = serviceCategories;
-	}
-	public List<CategoryDefinition> getProductCategories() {
-		return productCategories;
-	}
-	public void setProductCategories(List<CategoryDefinition> productCategories) {
-		this.productCategories = productCategories;
-	}
+
+    private List<CategoryDefinition> resourceCategories;
+    private List<CategoryDefinition> serviceCategories;
+    private List<CategoryDefinition> productCategories;
+
+    public List<CategoryDefinition> getResourceCategories() {
+        return resourceCategories;
+    }
+    public void setResourceCategories(List<CategoryDefinition> resourceCategories) {
+        this.resourceCategories = resourceCategories;
+    }
+    public List<CategoryDefinition> getServiceCategories() {
+        return serviceCategories;
+    }
+    public void setServiceCategories(List<CategoryDefinition> serviceCategories) {
+        this.serviceCategories = serviceCategories;
+    }
+    public List<CategoryDefinition> getProductCategories() {
+        return productCategories;
+    }
+    public void setProductCategories(List<CategoryDefinition> productCategories) {
+        this.productCategories = productCategories;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java
index eaf887b..f324cf8 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java
@@ -20,23 +20,13 @@
 
 package org.openecomp.sdc.be.ui.model;
 
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.model.category.CategoryDefinition;
+
 import java.util.List;
 import java.util.Map;
 
-import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
-import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-import org.openecomp.sdc.be.model.CapabilityDefinition;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceInput;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.InputDefinition;
-import org.openecomp.sdc.be.model.PolicyDefinition;
-import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
-import org.openecomp.sdc.be.model.RequirementDefinition;
-import org.openecomp.sdc.be.model.category.CategoryDefinition;
-
 public class UiComponentDataTransfer {
 
 
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentMetadata.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentMetadata.java
index 0719655..d0c7874 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentMetadata.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentMetadata.java
@@ -20,319 +20,350 @@
 
 package org.openecomp.sdc.be.ui.model;
 
-import java.util.List;
-import java.util.Map;
-
 import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 
+import java.util.List;
+import java.util.Map;
+
 public abstract class UiComponentMetadata {
 
-	private String uniqueId;
+    private String uniqueId;
 
-	private String name; // archiveName
+    private String name; // archiveName
 
-	private String version; // archiveVersion
+    private String version; // archiveVersion
 
-	private Boolean isHighestVersion;
+    private Boolean isHighestVersion;
 
-	private Long creationDate;
+    private Long creationDate;
+    private Long lastUpdateDate;
 
-	private Long lastUpdateDate;
+    private String description;
 
-	private String description;
+    private String lifecycleState;
 
-	private String lifecycleState;
+    private List<String> tags;
 
-	private List<String> tags;
+    private String icon;
 
-	private String icon;
+    private String UUID;
 
-	private String UUID;
+    private String normalizedName;
 
-	private String normalizedName;
+    private String systemName;
 
-	private String systemName;
+    private String contactId;
 
-	private String contactId;
+    private Map<String, String> allVersions;
 
-	private Map<String, String> allVersions;
+    private Boolean isDeleted;
 
-	private Boolean isDeleted;
+    private String projectCode;
 
-	private String projectCode;
+    private String csarUUID;
 
-	private String csarUUID;
+    private String csarVersion;
 
-	private String csarVersion;
+    private String importedToscaChecksum;
 
-	private String importedToscaChecksum;
+    private String invariantUUID;
 
-	private String invariantUUID;
+    private ComponentTypeEnum componentType;
 
-	private ComponentTypeEnum componentType;
-	
-	private List<CategoryDefinition> categories;
-	
-	private String creatorUserId;
-	
-	private String creatorFullName;
-	
-	private String lastUpdaterUserId;
-	
-	private String lastUpdaterFullName;
+    private List<CategoryDefinition> categories;
 
-	public UiComponentMetadata(){}
+    private String creatorUserId;
 
-	public UiComponentMetadata (List<CategoryDefinition> categories, ComponentMetadataDataDefinition metadata) {
-	
-		this.uniqueId = metadata.getUniqueId();
-		this.name = metadata.getName(); // archiveName
-		this.version = metadata.getVersion();
-		this.isHighestVersion = metadata.isHighestVersion();
-		this.creationDate = metadata.getCreationDate();
-		this.lastUpdateDate = metadata.getLastUpdateDate();
-		this.description = metadata.getDescription();
-		this.lifecycleState = metadata.getState();
-		this.tags = metadata.getTags();
-		this.icon = metadata.getIcon();
-		this.UUID = metadata.getUUID();
-		this.normalizedName = metadata.getNormalizedName();
-		this.systemName = metadata.getSystemName();
-		this.contactId = metadata.getContactId();
-		this.allVersions = metadata.getAllVersions();
-		this.projectCode = metadata.getProjectCode();
-		this.csarUUID = metadata.getCsarUUID();
-		this.csarVersion = metadata.getCsarVersion();
-		this.importedToscaChecksum = metadata.getImportedToscaChecksum();
-		this.invariantUUID = metadata.getInvariantUUID();
-		this.componentType = metadata.getComponentType();
-		this.categories = categories;
-		this.creatorUserId = metadata.getCreatorUserId();
-		this.creatorFullName = metadata.getCreatorFullName();
-		this.lastUpdaterFullName = metadata.getLastUpdaterFullName();
-		this.lastUpdaterUserId = metadata.getLastUpdaterUserId();
+    private String creatorFullName;
 
-	}
-	
-	
-	
-	public List<CategoryDefinition> getCategories() {
-		return categories;
-	}
+    private String lastUpdaterUserId;
 
-	public void setCategories(List<CategoryDefinition> categories) {
-		this.categories = categories;
-	}
+    private String lastUpdaterFullName;
 
-	
-	public String getUniqueId() {
-		return uniqueId;
-	}
+    //Archive/Restore
+    private Boolean isArchived;
+    private Long archiveTime;
+    private Boolean isVspArchived;
 
-	public void setUniqueId(String uniqueId) {
-		this.uniqueId = uniqueId;
-	}
+    public UiComponentMetadata(){}
 
-	public String getName() {
-		return name;
-	}
+    public UiComponentMetadata (List<CategoryDefinition> categories, ComponentMetadataDataDefinition metadata) {
 
-	public void setName(String name) {
-		this.name = name;
-	}
+        this.uniqueId = metadata.getUniqueId();
+        this.name = metadata.getName(); // archiveName
+        this.version = metadata.getVersion();
+        this.isHighestVersion = metadata.isHighestVersion();
+        this.creationDate = metadata.getCreationDate();
+        this.lastUpdateDate = metadata.getLastUpdateDate();
+        this.description = metadata.getDescription();
+        this.lifecycleState = metadata.getState();
+        this.tags = metadata.getTags();
+        this.icon = metadata.getIcon();
+        this.UUID = metadata.getUUID();
+        this.normalizedName = metadata.getNormalizedName();
+        this.systemName = metadata.getSystemName();
+        this.contactId = metadata.getContactId();
+        this.allVersions = metadata.getAllVersions();
+        this.projectCode = metadata.getProjectCode();
+        this.csarUUID = metadata.getCsarUUID();
+        this.csarVersion = metadata.getCsarVersion();
+        this.importedToscaChecksum = metadata.getImportedToscaChecksum();
+        this.invariantUUID = metadata.getInvariantUUID();
+        this.componentType = metadata.getComponentType();
+        this.categories = categories;
+        this.creatorUserId = metadata.getCreatorUserId();
+        this.creatorFullName = metadata.getCreatorFullName();
+        this.lastUpdaterFullName = metadata.getLastUpdaterFullName();
+        this.lastUpdaterUserId = metadata.getLastUpdaterUserId();
 
-	public String getVersion() {
-		return version;
-	}
+        //archive
+        this.isArchived = metadata.isArchived();
+        this.archiveTime = metadata.getArchiveTime();
+        this.isVspArchived = metadata.isVspArchived();
+    }
 
-	public void setVersion(String version) {
-		this.version = version;
-	}
 
-	public Boolean getIsHighestVersion() {
-		return isHighestVersion;
-	}
 
-	public void setIsHighestVersion(Boolean isHighestVersion) {
-		this.isHighestVersion = isHighestVersion;
-	}
+    public List<CategoryDefinition> getCategories() {
+        return categories;
+    }
 
-	public Long getCreationDate() {
-		return creationDate;
-	}
+    public void setCategories(List<CategoryDefinition> categories) {
+        this.categories = categories;
+    }
 
-	public void setCreationDate(Long creationDate) {
-		this.creationDate = creationDate;
-	}
 
-	public Long getLastUpdateDate() {
-		return lastUpdateDate;
-	}
+    public String getUniqueId() {
+        return uniqueId;
+    }
 
-	public void setLastUpdateDate(Long lastUpdateDate) {
-		this.lastUpdateDate = lastUpdateDate;
-	}
+    public void setUniqueId(String uniqueId) {
+        this.uniqueId = uniqueId;
+    }
 
-	public String getDescription() {
-		return description;
-	}
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public Boolean getIsHighestVersion() {
+        return isHighestVersion;
+    }
+
+    public void setIsHighestVersion(Boolean isHighestVersion) {
+        this.isHighestVersion = isHighestVersion;
+    }
+
+    public Long getCreationDate() {
+        return creationDate;
+    }
+
+    public void setCreationDate(Long creationDate) {
+        this.creationDate = creationDate;
+    }
+
+    public Long getLastUpdateDate() {
+        return lastUpdateDate;
+    }
+
+    public void setLastUpdateDate(Long lastUpdateDate) {
+        this.lastUpdateDate = lastUpdateDate;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getLifecycleState() {
+        return lifecycleState;
+    }
+
+    public void setLifecycleState(String state) {
+        this.lifecycleState = state;
+    }
+
+    public List<String> getTags() {
+        return tags;
+    }
+
+    public void setTags(List<String> tags) {
+        this.tags = tags;
+    }
 
-	public void setDescription(String description) {
-		this.description = description;
-	}
+    public String getIcon() {
+        return icon;
+    }
 
-	public String getLifecycleState() {
-		return lifecycleState;
-	}
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
 
-	public void setLifecycleState(String state) {
-		this.lifecycleState = state;
-	}
+    public String getUUID() {
+        return UUID;
+    }
 
-	public List<String> getTags() {
-		return tags;
-	}
+    public void setUUID(String uUID) {
+        UUID = uUID;
+    }
 
-	public void setTags(List<String> tags) {
-		this.tags = tags;
-	}
+    public String getNormalizedName() {
+        return normalizedName;
+    }
 
-	public String getIcon() {
-		return icon;
-	}
+    public void setNormalizedName(String normalizedName) {
+        this.normalizedName = normalizedName;
+    }
 
-	public void setIcon(String icon) {
-		this.icon = icon;
-	}
+    public String getSystemName() {
+        return systemName;
+    }
 
-	public String getUUID() {
-		return UUID;
-	}
+    public void setSystemName(String systemName) {
+        this.systemName = systemName;
+    }
 
-	public void setUUID(String uUID) {
-		UUID = uUID;
-	}
+    public String getContactId() {
+        return contactId;
+    }
 
-	public String getNormalizedName() {
-		return normalizedName;
-	}
+    public void setContactId(String contactId) {
+        this.contactId = contactId;
+    }
 
-	public void setNormalizedName(String normalizedName) {
-		this.normalizedName = normalizedName;
-	}
+    public Map<String, String> getAllVersions() {
+        return allVersions;
+    }
 
-	public String getSystemName() {
-		return systemName;
-	}
+    public void setAllVersions(Map<String, String> allVersions) {
+        this.allVersions = allVersions;
+    }
 
-	public void setSystemName(String systemName) {
-		this.systemName = systemName;
-	}
+    public Boolean getIsDeleted() {
+        return isDeleted;
+    }
 
-	public String getContactId() {
-		return contactId;
-	}
+    public void setIsDeleted(Boolean isDeleted) {
+        this.isDeleted = isDeleted;
+    }
 
-	public void setContactId(String contactId) {
-		this.contactId = contactId;
-	}
+    public String getProjectCode() {
+        return projectCode;
+    }
 
-	public Map<String, String> getAllVersions() {
-		return allVersions;
-	}
+    public void setProjectCode(String projectCode) {
+        this.projectCode = projectCode;
+    }
 
-	public void setAllVersions(Map<String, String> allVersions) {
-		this.allVersions = allVersions;
-	}
+    public String getCsarUUID() {
+        return csarUUID;
+    }
 
-	public Boolean getIsDeleted() {
-		return isDeleted;
-	}
+    public void setCsarUUID(String csarUUID) {
+        this.csarUUID = csarUUID;
+    }
 
-	public void setIsDeleted(Boolean isDeleted) {
-		this.isDeleted = isDeleted;
-	}
+    public String getCsarVersion() {
+        return csarVersion;
+    }
 
-	public String getProjectCode() {
-		return projectCode;
-	}
+    public void setCsarVersion(String csarVersion) {
+        this.csarVersion = csarVersion;
+    }
 
-	public void setProjectCode(String projectCode) {
-		this.projectCode = projectCode;
-	}
+    public String getImportedToscaChecksum() {
+        return importedToscaChecksum;
+    }
 
-	public String getCsarUUID() {
-		return csarUUID;
-	}
+    public void setImportedToscaChecksum(String importedToscaChecksum) {
+        this.importedToscaChecksum = importedToscaChecksum;
+    }
 
-	public void setCsarUUID(String csarUUID) {
-		this.csarUUID = csarUUID;
-	}
+    public String getInvariantUUID() {
+        return invariantUUID;
+    }
 
-	public String getCsarVersion() {
-		return csarVersion;
-	}
+    public void setInvariantUUID(String invariantUUID) {
+        this.invariantUUID = invariantUUID;
+    }
 
-	public void setCsarVersion(String csarVersion) {
-		this.csarVersion = csarVersion;
-	}
+    public ComponentTypeEnum getComponentType() {
+        return componentType;
+    }
 
-	public String getImportedToscaChecksum() {
-		return importedToscaChecksum;
-	}
+    public void setComponentType(ComponentTypeEnum componentType) {
+        this.componentType = componentType;
+    }
 
-	public void setImportedToscaChecksum(String importedToscaChecksum) {
-		this.importedToscaChecksum = importedToscaChecksum;
-	}
+    public String getCreatorUserId() {
+        return creatorUserId;
+    }
 
-	public String getInvariantUUID() {
-		return invariantUUID;
-	}
+    public void setCreatorUserId(String creatorUserId) {
+        this.creatorUserId = creatorUserId;
+    }
 
-	public void setInvariantUUID(String invariantUUID) {
-		this.invariantUUID = invariantUUID;
-	}
+    public String getCreatorFullName() {
+        return creatorFullName;
+    }
 
-	public ComponentTypeEnum getComponentType() {
-		return componentType;
-	}
+    public void setCreatorFullName(String creatorFullName) {
+        this.creatorFullName = creatorFullName;
+    }
 
-	public void setComponentType(ComponentTypeEnum componentType) {
-		this.componentType = componentType;
-	}
+    public String getLastUpdaterUserId() {
+        return lastUpdaterUserId;
+    }
 
-	public String getCreatorUserId() {
-		return creatorUserId;
-	}
+    public void setLastUpdaterUserId(String lastUpdaterUserId) {
+        this.lastUpdaterUserId = lastUpdaterUserId;
+    }
 
-	public void setCreatorUserId(String creatorUserId) {
-		this.creatorUserId = creatorUserId;
-	}
+    public String getLastUpdaterFullName() {
+        return lastUpdaterFullName;
+    }
 
-	public String getCreatorFullName() {
-		return creatorFullName;
-	}
+    public void setLastUpdaterFullName(String lastUpdaterFullName) {
+        this.lastUpdaterFullName = lastUpdaterFullName;
+    }
 
-	public void setCreatorFullName(String creatorFullName) {
-		this.creatorFullName = creatorFullName;
-	}
+    public Boolean isArchived() {
+        return isArchived;
+    }
 
-	public String getLastUpdaterUserId() {
-		return lastUpdaterUserId;
-	}
+    public void setArchived(Boolean archived) {
+        isArchived = archived;
+    }
 
-	public void setLastUpdaterUserId(String lastUpdaterUserId) {
-		this.lastUpdaterUserId = lastUpdaterUserId;
-	}
+    public Long getArchiveTime() {
+        return archiveTime;
+    }
 
-	public String getLastUpdaterFullName() {
-		return lastUpdaterFullName;
-	}
+    public void setArchiveTime(Long archiveTime) {
+        this.archiveTime = archiveTime;
+    }
 
-	public void setLastUpdaterFullName(String lastUpdaterFullName) {
-		this.lastUpdaterFullName = lastUpdaterFullName;
-	}
+    public Boolean isVspArchived() {
+        return isVspArchived;
+    }
 
+    public void setVspArchived(Boolean vspArchived) {
+        isVspArchived = vspArchived;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransfer.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransfer.java
index 9c0d25b..32e4b10 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransfer.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransfer.java
@@ -20,103 +20,103 @@
 
 package org.openecomp.sdc.be.ui.model;
 
-import java.util.List;
-import java.util.Map;
-
 import org.openecomp.sdc.be.datatypes.elements.InterfaceOperationDataDefinition;
 import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 
+import java.util.List;
+import java.util.Map;
+
 public class UiResourceDataTransfer extends UiComponentDataTransfer{
-	
-	private UiResourceMetadata metadata;
 
-	private List<String> derivedFrom;
+    private UiResourceMetadata metadata;
 
-	private List<String> derivedList;
+    private List<String> derivedFrom;
 
-	private List<PropertyDefinition> properties;
+    private List<String> derivedList;
 
-	private List<PropertyDefinition> attributes;
+    private List<PropertyDefinition> properties;
 
-	private Map<String, InterfaceDefinition> interfaces;
+    private List<PropertyDefinition> attributes;
 
-	private List<String> defaultCapabilities;
-	
-	private List<AdditionalInformationDefinition> additionalInformation;
-	private Map<String, InterfaceOperationDataDefinition> interfaceOperations;
-	
-	public UiResourceDataTransfer(){}
-	
-	public List<AdditionalInformationDefinition> getAdditionalInformation() {
-		return additionalInformation;
-	}
+    private Map<String, InterfaceDefinition> interfaces;
 
-	public void setAdditionalInformation(List<AdditionalInformationDefinition> additionalInformation) {
-		this.additionalInformation = additionalInformation;
-	}
+    private List<String> defaultCapabilities;
 
-	public UiResourceMetadata getMetadata() {
-		return metadata;
-	}
+    private Map<String, InterfaceOperationDataDefinition> interfaceOperations;
 
-	public void setMetadata(UiResourceMetadata metadata) {
-		this.metadata = metadata;
-	}
+    public UiResourceDataTransfer(){}
 
-	public List<String> getDerivedFrom() {
-		return derivedFrom;
-	}
+    public List<AdditionalInformationDefinition> getAdditionalInformation() {
+        return additionalInformation;
+    }
 
-	public void setDerivedFrom(List<String> derivedFrom) {
-		this.derivedFrom = derivedFrom;
-	}
+    public void setAdditionalInformation(List<AdditionalInformationDefinition> additionalInformation) {
+        this.additionalInformation = additionalInformation;
+    }
 
-	public List<String> getDerivedList() {
-		return derivedList;
-	}
+    public UiResourceMetadata getMetadata() {
+        return metadata;
+    }
 
-	public void setDerivedList(List<String> derivedList) {
-		this.derivedList = derivedList;
-	}
+    public void setMetadata(UiResourceMetadata metadata) {
+        this.metadata = metadata;
+    }
 
-	public List<PropertyDefinition> getProperties() {
-		return properties;
-	}
+    public List<String> getDerivedFrom() {
+        return derivedFrom;
+    }
 
-	public void setProperties(List<PropertyDefinition> properties) {
-		this.properties = properties;
-	}
+    public void setDerivedFrom(List<String> derivedFrom) {
+        this.derivedFrom = derivedFrom;
+    }
 
-	public List<PropertyDefinition> getAttributes() {
-		return attributes;
-	}
+    public List<String> getDerivedList() {
+        return derivedList;
+    }
 
-	public void setAttributes(List<PropertyDefinition> attributes) {
-		this.attributes = attributes;
-	}
+    public void setDerivedList(List<String> derivedList) {
+        this.derivedList = derivedList;
+    }
 
-	public Map<String, InterfaceDefinition> getInterfaces() {
-		return interfaces;
-	}
+    public List<PropertyDefinition> getProperties() {
+        return properties;
+    }
 
-	public void setInterfaces(Map<String, InterfaceDefinition> interfaces) {
-		this.interfaces = interfaces;
-	}
+    public void setProperties(List<PropertyDefinition> properties) {
+        this.properties = properties;
+    }
 
-	public List<String> getDefaultCapabilities() {
-		return defaultCapabilities;
-	}
+    public List<PropertyDefinition> getAttributes() {
+        return attributes;
+    }
 
-	public void setDefaultCapabilities(List<String> defaultCapabilities) {
-		this.defaultCapabilities = defaultCapabilities;
-	}
-	public Map<String, InterfaceOperationDataDefinition> getInterfaceOperations() {
-		return interfaceOperations;
-	}
+    public void setAttributes(List<PropertyDefinition> attributes) {
+        this.attributes = attributes;
+    }
 
-	public void setInterfaceOperations(Map<String, InterfaceOperationDataDefinition> interfaceOperations) {
-		this.interfaceOperations = interfaceOperations;
-	}
+    public Map<String, InterfaceDefinition> getInterfaces() {
+        return interfaces;
+    }
+
+    public void setInterfaces(Map<String, InterfaceDefinition> interfaces) {
+        this.interfaces = interfaces;
+    }
+
+    public List<String> getDefaultCapabilities() {
+        return defaultCapabilities;
+    }
+
+    public void setDefaultCapabilities(List<String> defaultCapabilities) {
+        this.defaultCapabilities = defaultCapabilities;
+    }
+    public Map<String, InterfaceOperationDataDefinition> getInterfaceOperations() {
+        return interfaceOperations;
+    }
+
+    public void setInterfaceOperations(Map<String, InterfaceOperationDataDefinition> interfaceOperations) {
+        this.interfaceOperations = interfaceOperations;
+    }
+
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceMetadata.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceMetadata.java
index 0923acb..d84ce25 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceMetadata.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceMetadata.java
@@ -20,112 +20,112 @@
 
 package org.openecomp.sdc.be.ui.model;
 
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 
+import java.util.List;
+
 public class UiResourceMetadata extends UiComponentMetadata {
-	
-	private String vendorName;
-	private String vendorRelease;
-	private String resourceVendorModelNumber;
-	private ResourceTypeEnum resourceType = ResourceTypeEnum.VFC;
-	private Boolean isAbstract;
-	private String cost;
-	private String licenseType;
-	private String toscaResourceName;
-	private List<String> derivedFrom;
-	
-	
-	public UiResourceMetadata(List<CategoryDefinition> categories, List<String> derivedFrom, ResourceMetadataDataDefinition metadata) {
-		super(categories, metadata);
-		this.vendorName = metadata.getVendorName();
-		this.vendorRelease = metadata.getVendorRelease();
-		this.resourceVendorModelNumber = metadata.getResourceVendorModelNumber();
-		this.resourceType = metadata.getResourceType();
-		this.cost = metadata.getCost();
-		this.licenseType = metadata.getLicenseType();
-		this.toscaResourceName = metadata.getToscaResourceName();
-		this.derivedFrom = derivedFrom;
-	}
-	
-	public UiResourceMetadata(){}
-	
-	public List<String> getDerivedFrom() {
-		return derivedFrom;
-	}
+
+    private String vendorName;
+    private String vendorRelease;
+    private String resourceVendorModelNumber;
+    private ResourceTypeEnum resourceType = ResourceTypeEnum.VFC;
+    private Boolean isAbstract;
+    private String cost;
+    private String licenseType;
+    private String toscaResourceName;
+    private List<String> derivedFrom;
 
 
-	public void setDerivedFrom(List<String> derivedFrom) {
-		this.derivedFrom = derivedFrom;
-	}
+    public UiResourceMetadata(List<CategoryDefinition> categories, List<String> derivedFrom, ResourceMetadataDataDefinition metadata) {
+        super(categories, metadata);
+        this.vendorName = metadata.getVendorName();
+        this.vendorRelease = metadata.getVendorRelease();
+        this.resourceVendorModelNumber = metadata.getResourceVendorModelNumber();
+        this.resourceType = metadata.getResourceType();
+        this.cost = metadata.getCost();
+        this.licenseType = metadata.getLicenseType();
+        this.toscaResourceName = metadata.getToscaResourceName();
+        this.derivedFrom = derivedFrom;
+    }
 
-	
-	public String getVendorName() {
-		return vendorName;
-	}
+    public UiResourceMetadata(){}
 
-	public void setVendorName(String vendorName) {
-		this.vendorName = vendorName;
-	}
+    public List<String> getDerivedFrom() {
+        return derivedFrom;
+    }
 
-	public String getVendorRelease() {
-		return vendorRelease;
-	}
 
-	public void setVendorRelease(String vendorRelease) {
-		this.vendorRelease = vendorRelease;
-	}
-	
-	public String getResourceVendorModelNumber() {
-		return resourceVendorModelNumber;
-	}
+    public void setDerivedFrom(List<String> derivedFrom) {
+        this.derivedFrom = derivedFrom;
+    }
 
-	public void setResourceVendorModelNumber(String resourceVendorModelNumber) {
-		this.resourceVendorModelNumber = resourceVendorModelNumber;
-	}
 
-	public ResourceTypeEnum getResourceType() {
-		return resourceType;
-	}
+    public String getVendorName() {
+        return vendorName;
+    }
 
-	public void setResourceType(ResourceTypeEnum resourceType) {
-		this.resourceType = resourceType;
-	}
+    public void setVendorName(String vendorName) {
+        this.vendorName = vendorName;
+    }
 
-	public Boolean getIsAbstract() {
-		return isAbstract;
-	}
+    public String getVendorRelease() {
+        return vendorRelease;
+    }
 
-	public void setIsAbstract(Boolean isAbstract) {
-		this.isAbstract = isAbstract;
-	}
+    public void setVendorRelease(String vendorRelease) {
+        this.vendorRelease = vendorRelease;
+    }
 
-	public String getCost() {
-		return cost;
-	}
+    public String getResourceVendorModelNumber() {
+        return resourceVendorModelNumber;
+    }
 
-	public void setCost(String cost) {
-		this.cost = cost;
-	}
+    public void setResourceVendorModelNumber(String resourceVendorModelNumber) {
+        this.resourceVendorModelNumber = resourceVendorModelNumber;
+    }
 
-	public String getLicenseType() {
-		return licenseType;
-	}
+    public ResourceTypeEnum getResourceType() {
+        return resourceType;
+    }
 
-	public void setLicenseType(String licenseType) {
-		this.licenseType = licenseType;
-	}
+    public void setResourceType(ResourceTypeEnum resourceType) {
+        this.resourceType = resourceType;
+    }
 
-	public String getToscaResourceName() {
-		return toscaResourceName;
-	}
+    public Boolean getIsAbstract() {
+        return isAbstract;
+    }
 
-	public void setToscaResourceName(String toscaResourceName) {
-		this.toscaResourceName = toscaResourceName;
-	}
+    public void setIsAbstract(Boolean isAbstract) {
+        this.isAbstract = isAbstract;
+    }
+
+    public String getCost() {
+        return cost;
+    }
+
+    public void setCost(String cost) {
+        this.cost = cost;
+    }
+
+    public String getLicenseType() {
+        return licenseType;
+    }
+
+    public void setLicenseType(String licenseType) {
+        this.licenseType = licenseType;
+    }
+
+    public String getToscaResourceName() {
+        return toscaResourceName;
+    }
+
+    public void setToscaResourceName(String toscaResourceName) {
+        this.toscaResourceName = toscaResourceName;
+    }
 
 
 
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceDataTransfer.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceDataTransfer.java
index 197f388..b2c2f7a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceDataTransfer.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceDataTransfer.java
@@ -20,38 +20,38 @@
 
 package org.openecomp.sdc.be.ui.model;
 
-import java.util.Map;
-
 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
 import org.openecomp.sdc.be.model.ArtifactDefinition;
+
+import java.util.Map;
 public class UiServiceDataTransfer extends UiComponentDataTransfer {
-	
 
-	private Map<String, ArtifactDefinition> serviceApiArtifacts;
-	private Map<String, ForwardingPathDataDefinition> forwardingPaths;
-	private UiServiceMetadata metadata;
-	
-	public UiServiceMetadata getMetadata() {
-		return metadata;
-	}
 
-	public void setMetadata(UiServiceMetadata metadata) {
-		this.metadata = metadata;
-	}
+    private Map<String, ArtifactDefinition> serviceApiArtifacts;
+    private Map<String, ForwardingPathDataDefinition> forwardingPaths;
+    private UiServiceMetadata metadata;
 
-	public Map<String, ArtifactDefinition> getServiceApiArtifacts() {
-		return serviceApiArtifacts;
-	}
+    public UiServiceMetadata getMetadata() {
+        return metadata;
+    }
 
-	public void setServiceApiArtifacts(Map<String, ArtifactDefinition> serviceApiArtifacts) {
-		this.serviceApiArtifacts = serviceApiArtifacts;
-	}
+    public void setMetadata(UiServiceMetadata metadata) {
+        this.metadata = metadata;
+    }
 
-	public java.util.Map<String, org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition> getForwardingPaths() {
-		return forwardingPaths;
-	}
+    public Map<String, ArtifactDefinition> getServiceApiArtifacts() {
+        return serviceApiArtifacts;
+    }
 
-	public void setForwardingPaths(java.util.Map<String, org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition> forwardingPaths) {
-		this.forwardingPaths = forwardingPaths;
-	}
+    public void setServiceApiArtifacts(Map<String, ArtifactDefinition> serviceApiArtifacts) {
+        this.serviceApiArtifacts = serviceApiArtifacts;
+    }
+
+    public java.util.Map<String, org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition> getForwardingPaths() {
+        return forwardingPaths;
+    }
+
+    public void setForwardingPaths(java.util.Map<String, org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition> forwardingPaths) {
+        this.forwardingPaths = forwardingPaths;
+    }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceMetadata.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceMetadata.java
index 3ab45f2..891ac1f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceMetadata.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceMetadata.java
@@ -20,11 +20,11 @@
 
 package org.openecomp.sdc.be.ui.model;
 
-import java.util.List;
-
 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 
+import java.util.List;
+
 public class UiServiceMetadata extends UiComponentMetadata {
 	
 	private String distributionStatus;
@@ -33,6 +33,7 @@
 	private String serviceType;
 	private String serviceRole;
 	private String environmentContext;
+	private String instantiationType;
 
 	public UiServiceMetadata(List<CategoryDefinition> categories, ServiceMetadataDataDefinition metadata) {
 		super(categories, metadata);
@@ -42,49 +43,58 @@
 		this.serviceType = metadata.getServiceType();
 		this.serviceRole = metadata.getServiceRole();
 		this.environmentContext = metadata.getEnvironmentContext();
-	}	
+		this.instantiationType = metadata.getInstantiationType();
+	}
 	
 	public String getDistributionStatus() {
 		return distributionStatus;
 	}
 
-	public void setDistributionStatus(String distributionStatus) {
-		this.distributionStatus = distributionStatus;
-	}
-	
-	public Boolean getEcompGeneratedNaming() {
-		return ecompGeneratedNaming;
-	}
+    public void setDistributionStatus(String distributionStatus) {
+        this.distributionStatus = distributionStatus;
+    }
 
-	public void setEcompGeneratedNaming(Boolean ecompGeneratedNaming) {
-		this.ecompGeneratedNaming = ecompGeneratedNaming;
-	}
+    public Boolean getEcompGeneratedNaming() {
+        return ecompGeneratedNaming;
+    }
 
-	public String getNamingPolicy() {
-		return namingPolicy;
-	}
+    public void setEcompGeneratedNaming(Boolean ecompGeneratedNaming) {
+        this.ecompGeneratedNaming = ecompGeneratedNaming;
+    }
 
-	public void setNamingPolicy(String namingPolicy) {
-		this.namingPolicy = namingPolicy;
-	}
-	
-	public String getServiceType() {
-		return serviceType;
-	}
+    public String getNamingPolicy() {
+        return namingPolicy;
+    }
 
-	public void setServiceType(String serviceType) {
-		this.serviceType = serviceType;
-	}
-	
-	public String getServiceRole() {
-		return serviceRole;
-	}
+    public void setNamingPolicy(String namingPolicy) {
+        this.namingPolicy = namingPolicy;
+    }
+
+    public String getServiceType() {
+        return serviceType;
+    }
+
+    public void setServiceType(String serviceType) {
+        this.serviceType = serviceType;
+    }
+
+    public String getServiceRole() {
+        return serviceRole;
+    }
 
 	public void setServiceRole(String serviceRole) {
 		this.serviceRole = serviceRole;
 	}
 
-	public String getEnvironmentContext() { return environmentContext; }
+	public String getInstantiationType() {
+		return instantiationType;
+	}
 
-	public void setEnvironmentContext(String environmentContext) { this.environmentContext = environmentContext; }
+	public void setInstantiationType(String instantiationType) {
+		this.instantiationType = instantiationType;
+	}
+
+    public String getEnvironmentContext() { return environmentContext; }
+
+    public void setEnvironmentContext(String environmentContext) { this.environmentContext = environmentContext; }
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.java
index 1d692fd..f83d888 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.java
@@ -20,226 +20,217 @@
 
 package org.openecomp.sdc.be.unittests.utils;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
-import org.openecomp.sdc.be.model.CapabilityDefinition;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.RequirementDefinition;
-import org.openecomp.sdc.be.model.Resource;
-import org.openecomp.sdc.be.resources.data.CapabilityData;
-import org.openecomp.sdc.be.resources.data.CapabilityInstData;
-import org.openecomp.sdc.be.resources.data.PropertyData;
-import org.openecomp.sdc.be.resources.data.PropertyValueData;
-import org.openecomp.sdc.be.resources.data.RequirementData;
-import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
+import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.resources.data.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
 
 public final class FactoryUtils {
+    private static final String STRING = "string";
+
 	private FactoryUtils() {
-	};
+    }
 
-	public static final class Constants {
-		public static final String DEFAULT_CAPABILITY_TYPE = "tosca.capabilities.Node";
-	}
+    public static final class Constants {
+        public static final String DEFAULT_CAPABILITY_TYPE = "tosca.capabilities.Node";
+    }
 
-	public static Resource createVFWithRI(String riVersion) {
-		Resource vf = createVF();
-		ComponentInstance ri = createResourceInstanceWithVersion(riVersion);
-		addComponentInstanceToVF(vf, ri);
-		return vf;
-	}
+    public static Resource createVFWithRI(String riVersion) {
+        Resource vf = createVF();
+        ComponentInstance ri = createResourceInstanceWithVersion(riVersion);
+        addComponentInstanceToVF(vf, ri);
+        return vf;
+    }
 
-	public static Resource createVF() {
-		Resource resource = new Resource();
-		String uniqueId = UUID.randomUUID().toString();
-		resource.setUniqueId(uniqueId);
-		return resource;
-	}
-	
-	public static ResourceMetadataData createResourceByType(String resourceType) {
-		ResourceMetadataData resource = new ResourceMetadataData();
-		String uniqueId = UUID.randomUUID().toString();
-		resource.getMetadataDataDefinition().setHighestVersion(true);
-		resource.getMetadataDataDefinition().setUniqueId(uniqueId);
-		((ResourceMetadataDataDefinition)resource.getMetadataDataDefinition()).setResourceType(ResourceTypeEnum.getTypeIgnoreCase(resourceType));
-		return resource;
-	}
+    public static Resource createVF() {
+        Resource resource = new Resource();
+        String uniqueId = UUID.randomUUID().toString();
+        resource.setUniqueId(uniqueId);
+        return resource;
+    }
 
-	public static void addComponentInstanceToVF(Resource vf, ComponentInstance resourceInstance) {
-		List<ComponentInstance> componentsInstances = vf.getComponentInstances() != null ? vf.getComponentInstances()
-				: new ArrayList<>();
-		componentsInstances.add(resourceInstance);
-		vf.setComponentInstances(componentsInstances);
-	}
+    public static ResourceMetadataData createResourceByType(String resourceType) {
+        ResourceMetadataData resource = new ResourceMetadataData();
+        String uniqueId = UUID.randomUUID().toString();
+        resource.getMetadataDataDefinition().setHighestVersion(true);
+        resource.getMetadataDataDefinition().setUniqueId(uniqueId);
+        ((ResourceMetadataDataDefinition)resource.getMetadataDataDefinition()).setResourceType(ResourceTypeEnum.getTypeIgnoreCase(resourceType));
+        return resource;
+    }
 
-	public static ComponentInstance createResourceInstance() {
-		ComponentInstance ri = new ComponentInstance();
-		ri.setComponentVersion("0.1");
-		String uniqueId = UUID.randomUUID().toString();
-		ri.setComponentUid(uniqueId);
-		ri.setUniqueId(uniqueId);
-		ri.setName("genericRI" + uniqueId);
-		ri.setOriginType(OriginTypeEnum.VF);
-		return ri;
+    public static void addComponentInstanceToVF(Resource vf, ComponentInstance resourceInstance) {
+        List<ComponentInstance> componentsInstances = vf.getComponentInstances() != null ? vf.getComponentInstances()
+                : new ArrayList<>();
+        componentsInstances.add(resourceInstance);
+        vf.setComponentInstances(componentsInstances);
+    }
 
-	}
+    public static ComponentInstance createResourceInstance() {
+        ComponentInstance ri = new ComponentInstance();
+        ri.setComponentVersion("0.1");
+        String uniqueId = UUID.randomUUID().toString();
+        ri.setComponentUid(uniqueId);
+        ri.setUniqueId(uniqueId);
+        ri.setName("genericRI" + uniqueId);
+        ri.setOriginType(OriginTypeEnum.VF);
+        return ri;
 
-	public static ComponentInstance createResourceInstanceWithVersion(String riVersion) {
-		ComponentInstance ri = createResourceInstance();
-		ri.setComponentVersion(riVersion);
-		return ri;
-	}
+    }
 
-	public static CapabilityData createCapabilityData() {
-		CapabilityData capData = new CapabilityData();
-		String uniqueId = UUID.randomUUID().toString();
-		capData.setUniqueId(uniqueId);
+    public static ComponentInstance createResourceInstanceWithVersion(String riVersion) {
+        ComponentInstance ri = createResourceInstance();
+        ri.setComponentVersion(riVersion);
+        return ri;
+    }
 
-		capData.setType(Constants.DEFAULT_CAPABILITY_TYPE);
-		return capData;
-	}
+    public static CapabilityData createCapabilityData() {
+        CapabilityData capData = new CapabilityData();
+        String uniqueId = UUID.randomUUID().toString();
+        capData.setUniqueId(uniqueId);
 
-	public static RequirementData createRequirementData() {
-		RequirementData reqData = new RequirementData();
-		String uniqueId = UUID.randomUUID().toString();
-		reqData.setUniqueId(uniqueId);
-		return reqData;
-	}
+        capData.setType(Constants.DEFAULT_CAPABILITY_TYPE);
+        return capData;
+    }
 
-	public static CapabilityDefinition convertCapabilityDataToCapabilityDefinitionAddProperties(
-			CapabilityData capData) {
-		CapabilityDefinition capDef = new CapabilityDefinition();
-		capDef.setName("Cap2");
-		capDef.setDescription(capData.getDescription());
-		capDef.setUniqueId(capData.getUniqueId());
-		capDef.setValidSourceTypes(capData.getValidSourceTypes());
-		capDef.setType(capData.getType());
-		capDef.setProperties(new ArrayList<>());
-		ComponentInstanceProperty host = new ComponentInstanceProperty();
-		host.setUniqueId(UUID.randomUUID().toString());
-		host.setName("host");
-		host.setDefaultValue("defhost");
-		host.setType("string");
+    public static RequirementData createRequirementData() {
+        RequirementData reqData = new RequirementData();
+        String uniqueId = UUID.randomUUID().toString();
+        reqData.setUniqueId(uniqueId);
+        return reqData;
+    }
 
-		host.setSchema(new SchemaDefinition());
-		host.getSchema().setProperty(new PropertyDataDefinition());
-		host.getSchema().getProperty().setType("string");
+    public static CapabilityDefinition convertCapabilityDataToCapabilityDefinitionAddProperties(
+            CapabilityData capData) {
+        CapabilityDefinition capDef = new CapabilityDefinition();
+        capDef.setName("Cap2");
+        capDef.setDescription(capData.getDescription());
+        capDef.setUniqueId(capData.getUniqueId());
+        capDef.setValidSourceTypes(capData.getValidSourceTypes());
+        capDef.setType(capData.getType());
+        capDef.setProperties(new ArrayList<>());
+        ComponentInstanceProperty host = new ComponentInstanceProperty();
+        host.setUniqueId(UUID.randomUUID().toString());
+        host.setName("host");
+        host.setDefaultValue("defhost");
+        host.setType(STRING);
 
-		capDef.getProperties().add(host);
-		ComponentInstanceProperty port = new ComponentInstanceProperty();
-		port.setName("port");
-		port.setDefaultValue("defport");
-		port.setUniqueId(UUID.randomUUID().toString());
-		port.setType("string");
+        host.setSchema(new SchemaDefinition());
+        host.getSchema().setProperty(new PropertyDataDefinition());
+        host.getSchema().getProperty().setType(STRING);
 
-		port.setSchema(new SchemaDefinition());
-		port.getSchema().setProperty(new PropertyDataDefinition());
-		port.getSchema().getProperty().setType("string");
+        capDef.getProperties().add(host);
+        ComponentInstanceProperty port = new ComponentInstanceProperty();
+        port.setName("port");
+        port.setDefaultValue("defport");
+        port.setUniqueId(UUID.randomUUID().toString());
+        port.setType(STRING);
 
-		capDef.getProperties().add(port);
-		return capDef;
-	}
+        port.setSchema(new SchemaDefinition());
+        port.getSchema().setProperty(new PropertyDataDefinition());
+        port.getSchema().getProperty().setType(STRING);
 
-	public static List<ComponentInstanceProperty> createComponentInstancePropertyList() {
-		List<ComponentInstanceProperty> properties = new ArrayList<>();
-		ComponentInstanceProperty host = new ComponentInstanceProperty();
-		host.setUniqueId(UUID.randomUUID().toString());
-		host.setName("host");
-		host.setValue("newhost");
-		host.setType("string");
+        capDef.getProperties().add(port);
+        return capDef;
+    }
 
-		host.setSchema(new SchemaDefinition());
-		host.getSchema().setProperty(new PropertyDataDefinition());
-		host.getSchema().getProperty().setType("string");
+    public static List<ComponentInstanceProperty> createComponentInstancePropertyList() {
+        List<ComponentInstanceProperty> properties = new ArrayList<>();
+        ComponentInstanceProperty host = new ComponentInstanceProperty();
+        host.setUniqueId(UUID.randomUUID().toString());
+        host.setName("host");
+        host.setValue("newhost");
+        host.setType(STRING);
 
-		properties.add(host);
-		ComponentInstanceProperty port = new ComponentInstanceProperty();
-		port.setName("port");
-		port.setValue("newport");
-		port.setUniqueId(UUID.randomUUID().toString());
-		port.setType("string");
+        host.setSchema(new SchemaDefinition());
+        host.getSchema().setProperty(new PropertyDataDefinition());
+        host.getSchema().getProperty().setType(STRING);
 
-		port.setSchema(new SchemaDefinition());
-		port.getSchema().setProperty(new PropertyDataDefinition());
-		port.getSchema().getProperty().setType("string");
+        properties.add(host);
+        ComponentInstanceProperty port = new ComponentInstanceProperty();
+        port.setName("port");
+        port.setValue("newport");
+        port.setUniqueId(UUID.randomUUID().toString());
+        port.setType(STRING);
 
-		properties.add(port);
-		return properties;
-	}
+        port.setSchema(new SchemaDefinition());
+        port.getSchema().setProperty(new PropertyDataDefinition());
+        port.getSchema().getProperty().setType(STRING);
 
-	public static RequirementDefinition convertRequirementDataIDToRequirementDefinition(String reqDataId) {
-		RequirementDefinition reqDef = new RequirementDefinition();
-		reqDef.setUniqueId(reqDataId);
-		reqDef.setCapability(Constants.DEFAULT_CAPABILITY_TYPE);
-		return reqDef;
-	}
+        properties.add(port);
+        return properties;
+    }
 
-	public static GraphEdge createGraphEdge() {
-		GraphEdge graphEdge = new GraphEdge();
-		return graphEdge;
-	}
+    public static RequirementDefinition convertRequirementDataIDToRequirementDefinition(String reqDataId) {
+        RequirementDefinition reqDef = new RequirementDefinition();
+        reqDef.setUniqueId(reqDataId);
+        reqDef.setCapability(Constants.DEFAULT_CAPABILITY_TYPE);
+        return reqDef;
+    }
 
-	public static CapabilityInstData createCapabilityInstData() {
-		CapabilityInstData capInstData = new CapabilityInstData();
-		String uniqueId = UUID.randomUUID().toString();
-		capInstData.setUniqueId(uniqueId);
-		return capInstData;
-	}
+    public static GraphEdge createGraphEdge() {
+        return new GraphEdge();
+    }
 
-	public static PropertyValueData createPropertyData() {
-		PropertyValueData propData = new PropertyValueData();
-		String uniqueId = UUID.randomUUID().toString();
-		propData.setValue("localhost");
-		propData.setUniqueId(uniqueId);
-		return propData;
-	}
+    public static CapabilityInstData createCapabilityInstData() {
+        CapabilityInstData capInstData = new CapabilityInstData();
+        String uniqueId = UUID.randomUUID().toString();
+        capInstData.setUniqueId(uniqueId);
+        return capInstData;
+    }
 
-	public static PropertyData convertCapabilityDefinitionToCapabilityData(PropertyDefinition propDef) {
-		PropertyData propData = new PropertyData();
-		propData.getPropertyDataDefinition().setUniqueId(propDef.getUniqueId());
-		propData.getPropertyDataDefinition().setDefaultValue(propDef.getDefaultValue());
-		return propData;
-	}
+    public static PropertyValueData createPropertyData() {
+        PropertyValueData propData = new PropertyValueData();
+        String uniqueId = UUID.randomUUID().toString();
+        propData.setValue("localhost");
+        propData.setUniqueId(uniqueId);
+        return propData;
+    }
 
-	public static CapabilityDefinition convertCapabilityDataToCapabilityDefinitionRoot(CapabilityData capData) {
-		CapabilityDefinition capDef = new CapabilityDefinition();
-		capDef.setName("Cap1");
-		capDef.setDescription(capData.getDescription());
-		capDef.setUniqueId(capData.getUniqueId());
-		capDef.setValidSourceTypes(capData.getValidSourceTypes());
-		capDef.setType(capData.getType());
-		capDef.setProperties(new ArrayList<>());
-		ComponentInstanceProperty host = new ComponentInstanceProperty();
-		host.setUniqueId(UUID.randomUUID().toString());
-		host.setName("host");
-		host.setDefaultValue("roothost");
-		host.setType("string");
+    public static PropertyData convertCapabilityDefinitionToCapabilityData(PropertyDefinition propDef) {
+        PropertyData propData = new PropertyData();
+        propData.getPropertyDataDefinition().setUniqueId(propDef.getUniqueId());
+        propData.getPropertyDataDefinition().setDefaultValue(propDef.getDefaultValue());
+        return propData;
+    }
 
-		host.setSchema(new SchemaDefinition());
-		host.getSchema().setProperty(new PropertyDataDefinition());
-		host.getSchema().getProperty().setType("string");
+    public static CapabilityDefinition convertCapabilityDataToCapabilityDefinitionRoot(CapabilityData capData) {
+        CapabilityDefinition capDef = new CapabilityDefinition();
+        capDef.setName("Cap1");
+        capDef.setDescription(capData.getDescription());
+        capDef.setUniqueId(capData.getUniqueId());
+        capDef.setValidSourceTypes(capData.getValidSourceTypes());
+        capDef.setType(capData.getType());
+        capDef.setProperties(new ArrayList<>());
+        ComponentInstanceProperty host = new ComponentInstanceProperty();
+        host.setUniqueId(UUID.randomUUID().toString());
+        host.setName("host");
+        host.setDefaultValue("roothost");
+        host.setType(STRING);
 
-		capDef.getProperties().add(host);
-		ComponentInstanceProperty port = new ComponentInstanceProperty();
-		port.setName("port");
-		port.setDefaultValue("rootport");
-		port.setUniqueId(UUID.randomUUID().toString());
-		port.setType("string");
+        host.setSchema(new SchemaDefinition());
+        host.getSchema().setProperty(new PropertyDataDefinition());
+        host.getSchema().getProperty().setType(STRING);
 
-		port.setSchema(new SchemaDefinition());
-		port.getSchema().setProperty(new PropertyDataDefinition());
-		port.getSchema().getProperty().setType("string");
+        capDef.getProperties().add(host);
+        ComponentInstanceProperty port = new ComponentInstanceProperty();
+        port.setName("port");
+        port.setDefaultValue("rootport");
+        port.setUniqueId(UUID.randomUUID().toString());
+        port.setType(STRING);
 
-		capDef.getProperties().add(port);
-		return capDef;
-	}
+        port.setSchema(new SchemaDefinition());
+        port.getSchema().setProperty(new PropertyDataDefinition());
+        port.getSchema().getProperty().setType(STRING);
+
+        capDef.getProperties().add(port);
+        return capDef;
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/AdditionalInformationDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/AdditionalInformationDefinitionTest.java
index f8f1165..697cdbe 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/AdditionalInformationDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/AdditionalInformationDefinitionTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.LinkedList;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
 
+import java.util.LinkedList;
+
 
 public class AdditionalInformationDefinitionTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ArtifactDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ArtifactDefinitionTest.java
index 3c0034a..e374eea 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ArtifactDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ArtifactDefinitionTest.java
@@ -1,12 +1,12 @@
 package org.openecomp.sdc.be.model;
 
+import org.junit.Test;
+import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
+
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 
-import org.junit.Test;
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-
 
 public class ArtifactDefinitionTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ArtifactUiDownloadDataTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ArtifactUiDownloadDataTest.java
deleted file mode 100644
index dc80158..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ArtifactUiDownloadDataTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.openecomp.sdc.be.model;
-
-import org.junit.Test;
-
-public class ArtifactUiDownloadDataTest {
-
-	private ArtifactUiDownloadData createTestSubject() {
-		return new ArtifactUiDownloadData();
-	}
-
-	
-	@Test
-	public void testSetArtifactName() throws Exception {
-		ArtifactUiDownloadData testSubject;
-		String artifactName = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setArtifactName(artifactName);
-	}
-
-	
-	@Test
-	public void testSetBase64Contents() throws Exception {
-		ArtifactUiDownloadData testSubject;
-		String base64Contents = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setBase64Contents(base64Contents);
-	}
-
-	
-	@Test
-	public void testGetArtifactName() throws Exception {
-		ArtifactUiDownloadData testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getArtifactName();
-	}
-
-	
-	@Test
-	public void testGetBase64Contents() throws Exception {
-		ArtifactUiDownloadData testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getBase64Contents();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapReqDefTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapReqDefTest.java
index 6c7e879..3965426 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapReqDefTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapReqDefTest.java
@@ -1,11 +1,11 @@
 package org.openecomp.sdc.be.model;
 
+import org.junit.Test;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.junit.Test;
-
 
 public class CapReqDefTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityDefinitionTest.java
index ffe0a82..8fba70e 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityDefinitionTest.java
@@ -1,11 +1,11 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.LinkedList;
-import java.util.List;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
 
+import java.util.LinkedList;
+import java.util.List;
+
 
 public class CapabilityDefinitionTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityRequirementRelationshipTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityRequirementRelationshipTest.java
index 85cbef6..8528eed 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityRequirementRelationshipTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityRequirementRelationshipTest.java
@@ -70,11 +70,4 @@
 		testSubject.setRequirement(requirement);
 	}
 
-	@Test
-	public void testGetSerialversionuid() throws Exception {
-		long result;
-
-		// default test
-		result = CapabilityRequirementRelationship.getSerialversionuid();
-	}
 }
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityTypeDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityTypeDefinitionTest.java
index dde8059..117c0f6 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityTypeDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabilityTypeDefinitionTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.Map;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.CapabilityTypeDataDefinition;
 
+import java.util.Map;
+
 
 public class CapabilityTypeDefinitionTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabiltyInstanceTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabiltyInstanceTest.java
index ff13a6c..d18680e 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabiltyInstanceTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CapabiltyInstanceTest.java
@@ -1,9 +1,9 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.Map;
-
 import org.junit.Test;
 
+import java.util.Map;
+
 public class CapabiltyInstanceTest {
 
 	private CapabiltyInstance createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstInputsMapTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstInputsMapTest.java
index 006d4fc..95247c7 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstInputsMapTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstInputsMapTest.java
@@ -1,12 +1,13 @@
 package org.openecomp.sdc.be.model;
 
+import org.junit.Assert;
+import org.junit.Test;
+
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
-import org.junit.Test;
-
 public class ComponentInstInputsMapTest {
 
 	private ComponentInstInputsMap createTestSubject() {
@@ -46,7 +47,7 @@
 	@Test
 	public void testSetComponentInstancePropInput() throws Exception {
 		ComponentInstInputsMap testSubject;
-		Map<String, List<ComponentInstancePropInput>> componentInstanceProperties = null;
+		Map<String, List<ComponentInstancePropInput>> componentInstanceProperties = new HashMap<>();
 
 		// default test
 		testSubject = createTestSubject();
@@ -63,8 +64,7 @@
 		try {
 			testSubject.resolvePropertiesToDeclare();
 		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            Assert.assertTrue(e.getClass() == IllegalStateException.class);
 		}
 	}
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstanceInputTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstanceInputTest.java
index d02b05f..fbb4bd8 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstanceInputTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstanceInputTest.java
@@ -1,11 +1,11 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
 
+import java.util.List;
+
 
 public class ComponentInstanceInputTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstancePropertyTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstancePropertyTest.java
index a734722..cec822f 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstancePropertyTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstancePropertyTest.java
@@ -1,11 +1,11 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
 
+import java.util.List;
+
 
 public class ComponentInstancePropertyTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstanceTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstanceTest.java
index 39eba76..5c45ef4 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstanceTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentInstanceTest.java
@@ -1,12 +1,12 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-import java.util.Map;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
 
+import java.util.List;
+import java.util.Map;
+
 public class ComponentInstanceTest {
 
 	private ComponentInstance createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentParametersViewTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentParametersViewTest.java
index 8dd2d0d..d84b821 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentParametersViewTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ComponentParametersViewTest.java
@@ -1,12 +1,12 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.LinkedList;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 
+import java.util.LinkedList;
+
 public class ComponentParametersViewTest {
 
 	private ComponentParametersView createTestSubject() {
@@ -215,17 +215,6 @@
 
 	
 	@Test
-	public void testSetIgnoreAdditionalInformation() throws Exception {
-		ComponentParametersView testSubject;
-		boolean ignoreAdditionalInformation = false;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setIgnoreAdditionalInformation(ignoreAdditionalInformation);
-	}
-
-	
-	@Test
 	public void testIsIgnoreArtifacts() throws Exception {
 		ComponentParametersView testSubject;
 		boolean result;
@@ -301,16 +290,6 @@
 		result = testSubject.isIgnoreInterfaces();
 	}
 
-	
-	@Test
-	public void testSetIgnoreInterfaces() throws Exception {
-		ComponentParametersView testSubject;
-		boolean ignoreInterfaces = false;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setIgnoreInterfaces(ignoreInterfaces);
-	}
 
 	
 	@Test
@@ -345,16 +324,6 @@
 		result = testSubject.isIgnoreComponentInstancesAttributesFrom();
 	}
 
-	
-	@Test
-	public void testSetIgnoreComponentInstancesAttributesFrom() throws Exception {
-		ComponentParametersView testSubject;
-		boolean ignoreComponentInstancesAttributesFrom = false;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setIgnoreComponentInstancesAttributesFrom(ignoreComponentInstancesAttributesFrom);
-	}
 
 	
 	@Test
@@ -367,16 +336,6 @@
 		result = testSubject.isIgnoreDerivedFrom();
 	}
 
-	
-	@Test
-	public void testSetIgnoreDerivedFrom() throws Exception {
-		ComponentParametersView testSubject;
-		boolean ignoreDerivedFrom = false;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setIgnoreDerivedFrom(ignoreDerivedFrom);
-	}
 
 	
 	@Test
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CsarInfoTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/CsarInfoTest.java
deleted file mode 100644
index d7444e3..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/CsarInfoTest.java
+++ /dev/null
@@ -1,201 +0,0 @@
-package org.openecomp.sdc.be.model;
-
-import java.util.Map;
-import java.util.Queue;
-
-import org.junit.Test;
-
-
-public class CsarInfoTest {
-
-	private CsarInfo createTestSubject() {
-		return new CsarInfo("", new User(), "", null, "", false);
-	}
-
-	
-	@Test
-	public void testGetVfResourceName() throws Exception {
-		CsarInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getVfResourceName();
-	}
-
-	
-	@Test
-	public void testSetVfResourceName() throws Exception {
-		CsarInfo testSubject;
-		String vfResourceName = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setVfResourceName(vfResourceName);
-	}
-
-	
-	@Test
-	public void testGetModifier() throws Exception {
-		CsarInfo testSubject;
-		User result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getModifier();
-	}
-
-	
-	@Test
-	public void testSetModifier() throws Exception {
-		CsarInfo testSubject;
-		User modifier = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setModifier(modifier);
-	}
-
-	
-	@Test
-	public void testGetCsarUUID() throws Exception {
-		CsarInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCsarUUID();
-	}
-
-	
-	@Test
-	public void testSetCsarUUID() throws Exception {
-		CsarInfo testSubject;
-		String csarUUID = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCsarUUID(csarUUID);
-	}
-
-	
-	@Test
-	public void testGetCsar() throws Exception {
-		CsarInfo testSubject;
-		Map<String, byte[]> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCsar();
-	}
-
-	
-	@Test
-	public void testSetCsar() throws Exception {
-		CsarInfo testSubject;
-		Map<String, byte[]> csar = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCsar(csar);
-	}
-
-	
-	@Test
-	public void testGetMainTemplateContent() throws Exception {
-		CsarInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getMainTemplateContent();
-	}
-
-	
-	@Test
-	public void testGetMappedToscaMainTemplate() throws Exception {
-		CsarInfo testSubject;
-		Map<String, Object> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getMappedToscaMainTemplate();
-	}
-
-	
-	@Test
-	public void testGetCreatedNodesToscaResourceNames() throws Exception {
-		CsarInfo testSubject;
-		Map<String, String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCreatedNodesToscaResourceNames();
-	}
-
-	
-	@Test
-	public void testSetCreatedNodesToscaResourceNames() throws Exception {
-		CsarInfo testSubject;
-		Map<String, String> createdNodesToscaResourceNames = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCreatedNodesToscaResourceNames(createdNodesToscaResourceNames);
-	}
-
-	
-	@Test
-	public void testGetCvfcToCreateQueue() throws Exception {
-		CsarInfo testSubject;
-		Queue<String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCvfcToCreateQueue();
-	}
-
-	
-	@Test
-	public void testSetCvfcToCreateQueue() throws Exception {
-		CsarInfo testSubject;
-		Queue<String> cvfcToCreateQueue = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCvfcToCreateQueue(cvfcToCreateQueue);
-	}
-
-	
-	@Test
-	public void testIsUpdate() throws Exception {
-		CsarInfo testSubject;
-		boolean result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.isUpdate();
-	}
-
-	
-	@Test
-	public void testSetUpdate() throws Exception {
-		CsarInfo testSubject;
-		boolean isUpdate = false;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setUpdate(isUpdate);
-	}
-
-	
-	@Test
-	public void testGetCreatedNodes() throws Exception {
-		CsarInfo testSubject;
-		Map<String, Resource> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCreatedNodes();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/DataTypeDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/DataTypeDefinitionTest.java
index 1b5abb8..d779827 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/DataTypeDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/DataTypeDefinitionTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
 
+import java.util.List;
+
 
 public class DataTypeDefinitionTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/FunctionalMenuInfoTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/FunctionalMenuInfoTest.java
deleted file mode 100644
index ca5d1a2..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/FunctionalMenuInfoTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.openecomp.sdc.be.model;
-
-import org.junit.Test;
-
-
-public class FunctionalMenuInfoTest {
-
-	private FunctionalMenuInfo createTestSubject() {
-		return new FunctionalMenuInfo();
-	}
-
-	
-	@Test
-	public void testGetFunctionalMenu() throws Exception {
-		FunctionalMenuInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getFunctionalMenu();
-	}
-
-	
-	@Test
-	public void testSetFunctionalMenu() throws Exception {
-		FunctionalMenuInfo testSubject;
-		String functionalMenu = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setFunctionalMenu(functionalMenu);
-	}
-
-	
-	@Test
-	public void testToString() throws Exception {
-		FunctionalMenuInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.toString();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupDefinitionTest.java
index 58709aa..f8b250d 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupDefinitionTest.java
@@ -1,12 +1,12 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.LinkedList;
-import java.util.List;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 
+import java.util.LinkedList;
+import java.util.List;
+
 
 public class GroupDefinitionTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupInstanceTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupInstanceTest.java
index 84acf9d..346e9d3 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupInstanceTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupInstanceTest.java
@@ -1,15 +1,14 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
+import mockit.Deencapsulation;
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 
-import mockit.Deencapsulation;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 
 public class GroupInstanceTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupTypeDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupTypeDefinitionTest.java
index 47e11e1..4d70048 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupTypeDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/GroupTypeDefinitionTest.java
@@ -1,11 +1,11 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.LinkedList;
-import java.util.List;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.GroupTypeDataDefinition;
 
+import java.util.HashMap;
+import java.util.List;
+
 
 public class GroupTypeDefinitionTest {
 
@@ -46,7 +46,7 @@
 
 		// default test
 		testSubject = createTestSubject();
-		testSubject.getCapabilityTypes();
+		testSubject.getCapabilities();
 	}
 	
 	@Test
@@ -55,7 +55,7 @@
 
 		// default test
 		testSubject = createTestSubject();
-		testSubject.setCapabilityTypes(new LinkedList<>());
+		testSubject.setCapabilities(new HashMap<>());
 	}
 	
 	@Test
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/InputDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/InputDefinitionTest.java
index e865f4e..0b8bdd5 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/InputDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/InputDefinitionTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 
+import java.util.List;
+
 
 public class InputDefinitionTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/InterfaceDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/InterfaceDefinitionTest.java
index 5a8e155..41cad06 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/InterfaceDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/InterfaceDefinitionTest.java
@@ -1,11 +1,11 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
 
+import java.util.HashMap;
+import java.util.Map;
+
 
 public class InterfaceDefinitionTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ModelTestBase.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ModelTestBase.java
index 04c9d51..ade46d8 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ModelTestBase.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ModelTestBase.java
@@ -20,17 +20,30 @@
 
 package org.openecomp.sdc.be.model;
 
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.openecomp.sdc.be.config.Configuration;
 import org.openecomp.sdc.be.config.ConfigurationManager;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.common.api.ConfigurationSource;
 import org.openecomp.sdc.common.impl.ExternalConfiguration;
 import org.openecomp.sdc.common.impl.FSConfigurationSource;
 
+import java.util.Iterator;
+
 public class ModelTestBase {
 
-	protected static ConfigurationManager configurationManager;
+    protected static ConfigurationManager configurationManager;
+    protected static final String CONTAINER_ID = "containerId";
+    protected static final String CONTAINER_NAME = "containerName";
 
-	public static void init() {
+    public static void init() {
 		String appConfigDir = "src/test/resources/config";
 		ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(),
 				appConfigDir);
@@ -42,4 +55,34 @@
 
 		configurationManager.setConfiguration(configuration);
 	}
+
+    protected void removeGraphVertices(Either<TitanGraph, TitanOperationStatus> graphResult) {
+        TitanGraph graph = graphResult.left().value();
+        Iterable<TitanVertex> vertices = graph.query().vertices();
+        if (vertices != null) {
+            Iterator<TitanVertex> iterator = vertices.iterator();
+            while (iterator.hasNext()) {
+                TitanVertex vertex = iterator.next();
+                vertex.remove();
+            }
+
+        }
+    }
+
+    protected PropertyDefinition createSimpleProperty(String defaultValue, String name, String type) {
+        PropertyDefinition prop1 = new PropertyDefinition();
+        prop1.setDefaultValue(defaultValue);
+        prop1.setName(name);
+        prop1.setType(type);
+        return prop1;
+    }
+
+    protected GraphVertex createBasicContainerGraphVertex() {
+        GraphVertex resource = new GraphVertex(VertexTypeEnum.TOPOLOGY_TEMPLATE);
+        resource.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, CONTAINER_ID);
+        resource.addMetadataProperty(GraphPropertyEnum.NAME, CONTAINER_NAME);
+        resource.setJsonMetadataField(JsonPresentationFields.NAME, CONTAINER_NAME);
+        resource.setJsonMetadataField(JsonPresentationFields.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
+        return resource;
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/NodeTypeInfoTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/NodeTypeInfoTest.java
deleted file mode 100644
index d6d39ae..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/NodeTypeInfoTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package org.openecomp.sdc.be.model;
-
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Test;
-
-
-public class NodeTypeInfoTest {
-
-	private NodeTypeInfo createTestSubject() {
-		return new NodeTypeInfo();
-	}
-
-	
-	@Test
-	public void testGetUnmarkedCopy() throws Exception {
-		NodeTypeInfo testSubject;
-		NodeTypeInfo result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getUnmarkedCopy();
-	}
-
-	
-	@Test
-	public void testGetType() throws Exception {
-		NodeTypeInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getType();
-	}
-
-	
-	@Test
-	public void testSetType() throws Exception {
-		NodeTypeInfo testSubject;
-		String type = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setType(type);
-	}
-
-	
-	@Test
-	public void testGetTemplateFileName() throws Exception {
-		NodeTypeInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getTemplateFileName();
-	}
-
-	
-	@Test
-	public void testSetTemplateFileName() throws Exception {
-		NodeTypeInfo testSubject;
-		String templateFileName = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setTemplateFileName(templateFileName);
-	}
-
-	
-	@Test
-	public void testGetDerivedFrom() throws Exception {
-		NodeTypeInfo testSubject;
-		List<String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getDerivedFrom();
-	}
-
-	
-	@Test
-	public void testSetDerivedFrom() throws Exception {
-		NodeTypeInfo testSubject;
-		List<String> derivedFrom = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setDerivedFrom(derivedFrom);
-	}
-
-	
-	@Test
-	public void testIsNested() throws Exception {
-		NodeTypeInfo testSubject;
-		boolean result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.isNested();
-	}
-
-	
-	@Test
-	public void testSetNested() throws Exception {
-		NodeTypeInfo testSubject;
-		boolean isNested = false;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setNested(isNested);
-	}
-
-	
-	@Test
-	public void testGetMappedToscaTemplate() throws Exception {
-		NodeTypeInfo testSubject;
-		Map<String, Object> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getMappedToscaTemplate();
-	}
-
-	
-	@Test
-	public void testSetMappedToscaTemplate() throws Exception {
-		NodeTypeInfo testSubject;
-		Map<String, Object> mappedToscaTemplate = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setMappedToscaTemplate(mappedToscaTemplate);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfoTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfoTest.java
index cec44b4..eeb1213 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfoTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfoTest.java
@@ -1,9 +1,9 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.Map;
-
 import org.junit.Test;
 
+import java.util.Map;
+
 public class ParsedToscaYamlInfoTest {
 
 	private ParsedToscaYamlInfo createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyDefinitionTest.java
index c7a21b8..f518f41 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyDefinitionTest.java
@@ -1,11 +1,11 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.HashMap;
-import java.util.LinkedList;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition;
 
+import java.util.HashMap;
+import java.util.LinkedList;
+
 public class PolicyDefinitionTest {
 
 	private PolicyDefinition createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyTargetDTOTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyTargetDTOTest.java
index 9559a23..5e32fa1 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyTargetDTOTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyTargetDTOTest.java
@@ -1,9 +1,9 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.junit.Test;
 
+import java.util.List;
+
 public class PolicyTargetDTOTest {
 
 	private PolicyTargetDTO createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyTypeDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyTypeDefinitionTest.java
index 3f57ecf..265b88b 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyTypeDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/PolicyTypeDefinitionTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.PolicyTypeDataDefinition;
 
+import java.util.List;
+
 
 public class PolicyTypeDefinitionTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ProductTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ProductTest.java
index 021e044..edde844 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ProductTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ProductTest.java
@@ -1,9 +1,9 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.List;
-
 import org.junit.Test;
 
+import java.util.List;
+
 
 public class ProductTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/PropertyDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/PropertyDefinitionTest.java
index 5a8888b..2cd8d37 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/PropertyDefinitionTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/PropertyDefinitionTest.java
@@ -1,12 +1,12 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.LinkedList;
-import java.util.List;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition.PropertyNames;
 
+import java.util.LinkedList;
+import java.util.List;
+
 
 public class PropertyDefinitionTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/RequirementImplDefTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/RequirementImplDefTest.java
deleted file mode 100644
index 58bccbe..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/RequirementImplDefTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package org.openecomp.sdc.be.model;
-
-import java.util.Map;
-
-import org.junit.Test;
-
-
-public class RequirementImplDefTest {
-
-	private RequirementImplDef createTestSubject() {
-		return new RequirementImplDef();
-	}
-
-	
-	@Test
-	public void testGetNodeId() throws Exception {
-		RequirementImplDef testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getNodeId();
-	}
-
-	
-	@Test
-	public void testSetNodeId() throws Exception {
-		RequirementImplDef testSubject;
-		String nodeId = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setNodeId(nodeId);
-	}
-
-	
-	@Test
-	public void testGetUniqueId() throws Exception {
-		RequirementImplDef testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getUniqueId();
-	}
-
-	
-	@Test
-	public void testSetUniqueId() throws Exception {
-		RequirementImplDef testSubject;
-		String uniqueId = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setUniqueId(uniqueId);
-	}
-
-	
-	@Test
-	public void testGetRequirementProperties() throws Exception {
-		RequirementImplDef testSubject;
-		Map<String, CapabiltyInstance> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getRequirementProperties();
-	}
-
-	
-	@Test
-	public void testSetRequirementProperties() throws Exception {
-		RequirementImplDef testSubject;
-		Map<String, CapabiltyInstance> requirementProperties = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setRequirementProperties(requirementProperties);
-	}
-
-	
-	@Test
-	public void testGetPoint() throws Exception {
-		RequirementImplDef testSubject;
-		Point result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getPoint();
-	}
-
-	
-	@Test
-	public void testSetPoint() throws Exception {
-		RequirementImplDef testSubject;
-		Point point = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setPoint(point);
-	}
-
-	
-	@Test
-	public void testToString() throws Exception {
-		RequirementImplDef testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.toString();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/RequirementInstanceTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/RequirementInstanceTest.java
deleted file mode 100644
index 83472b0..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/RequirementInstanceTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.openecomp.sdc.be.model;
-
-import org.junit.Test;
-
-
-public class RequirementInstanceTest {
-
-	private RequirementInstance createTestSubject() {
-		return new RequirementInstance();
-	}
-
-	
-	@Test
-	public void testGetNode() throws Exception {
-		RequirementInstance testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getNode();
-	}
-
-	
-	@Test
-	public void testSetNode() throws Exception {
-		RequirementInstance testSubject;
-		String node = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setNode(node);
-	}
-
-	
-	@Test
-	public void testGetRelationship() throws Exception {
-		RequirementInstance testSubject;
-		RelationshipImpl result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getRelationship();
-	}
-
-	
-	@Test
-	public void testSetRelationship() throws Exception {
-		RequirementInstance testSubject;
-		RelationshipImpl relationship = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setRelationship(relationship);
-	}
-
-	
-	@Test
-	public void testToString() throws Exception {
-		RequirementInstance testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.toString();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ResourceTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ResourceTest.java
index 53ddbb3..cf4ee08 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ResourceTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ResourceTest.java
@@ -1,16 +1,15 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
+import mockit.Deencapsulation;
 import org.junit.Assert;
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.InterfaceOperationDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
 import org.openecomp.sdc.be.unittests.utils.ModelConfDependentTest;
 
-import mockit.Deencapsulation;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 
 public class ResourceTest extends ModelConfDependentTest{
 
@@ -20,7 +19,7 @@
 
 	@Test
 	public void testCtor() throws Exception {
-		ComponentMetadataDefinition componentMetadataDefinition = new ComponentMetadataDefinition();
+		ComponentMetadataDefinition componentMetadataDefinition = new ResourceMetadataDefinition();
 		new Resource(componentMetadataDefinition);
 	}
 	
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ServiceTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ServiceTest.java
index 7dafe7d..d8f2840 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ServiceTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ServiceTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.Map;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
 
+import java.util.Map;
+
 public class ServiceTest {
 
 	private Service createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/TargetCapabilityRelDefTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/TargetCapabilityRelDefTest.java
index ab61011..8978ce7 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/TargetCapabilityRelDefTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/TargetCapabilityRelDefTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model;
 
+import org.junit.Test;
+
 import java.util.LinkedList;
 import java.util.List;
 
-import org.junit.Test;
-
 public class TargetCapabilityRelDefTest {
 
 	private TargetCapabilityRelDef createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadCapInfoTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadCapInfoTest.java
deleted file mode 100644
index 92075ba..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadCapInfoTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.openecomp.sdc.be.model;
-
-import java.util.List;
-
-import org.junit.Test;
-
-
-public class UploadCapInfoTest {
-
-	private UploadCapInfo createTestSubject() {
-		return new UploadCapInfo();
-	}
-
-	
-	@Test
-	public void testGetNode() throws Exception {
-		UploadCapInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getNode();
-	}
-
-	
-	@Test
-	public void testSetNode() throws Exception {
-		UploadCapInfo testSubject;
-		String node = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setNode(node);
-	}
-
-	
-	@Test
-	public void testGetValidSourceTypes() throws Exception {
-		UploadCapInfo testSubject;
-		List<String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getValidSourceTypes();
-	}
-
-	
-	@Test
-	public void testSetValidSourceTypes() throws Exception {
-		UploadCapInfo testSubject;
-		List<String> validSourceTypes = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setValidSourceTypes(validSourceTypes);
-	}
-
-	
-	@Test
-	public void testGetProperties() throws Exception {
-		UploadCapInfo testSubject;
-		List<UploadPropInfo> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getProperties();
-	}
-
-	
-	@Test
-	public void testSetProperties() throws Exception {
-		UploadCapInfo testSubject;
-		List<UploadPropInfo> properties = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setProperties(properties);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfoTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfoTest.java
index f23e04b..484681e 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfoTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfoTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model;
 
+import org.junit.Test;
+
 import java.util.List;
 import java.util.Map;
 
-import org.junit.Test;
-
 public class UploadComponentInstanceInfoTest {
 
 	private UploadComponentInstanceInfo createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadPropInfoTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadPropInfoTest.java
deleted file mode 100644
index 9cc0d1c..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadPropInfoTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.openecomp.sdc.be.model;
-
-import java.util.List;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
-
-
-public class UploadPropInfoTest {
-
-	private UploadPropInfo createTestSubject() {
-		return new UploadPropInfo();
-	}
-
-	
-	@Test
-	public void testGetGet_input() throws Exception {
-		UploadPropInfo testSubject;
-		List<GetInputValueDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getGet_input();
-	}
-
-	
-	@Test
-	public void testSetGet_input() throws Exception {
-		UploadPropInfo testSubject;
-		List<GetInputValueDataDefinition> get_input = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setGet_input(get_input);
-	}
-
-	
-	@Test
-	public void testGetValue() throws Exception {
-		UploadPropInfo testSubject;
-		Object result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getValue();
-	}
-
-	
-	@Test
-	public void testSetValue() throws Exception {
-		UploadPropInfo testSubject;
-		Object value = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setValue(value);
-	}
-
-	
-	@Test
-	public void testGetDescription() throws Exception {
-		UploadPropInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getDescription();
-	}
-
-	
-	@Test
-	public void testSetDescription() throws Exception {
-		UploadPropInfo testSubject;
-		String description = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setDescription(description);
-	}
-
-	
-	@Test
-	public void testIsPassword() throws Exception {
-		UploadPropInfo testSubject;
-		boolean result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.isPassword();
-	}
-
-	
-	@Test
-	public void testSetPassword() throws Exception {
-		UploadPropInfo testSubject;
-		boolean password = false;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setPassword(password);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadReqInfoTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadReqInfoTest.java
deleted file mode 100644
index 9aebec8..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadReqInfoTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.openecomp.sdc.be.model;
-
-import org.junit.Test;
-
-
-public class UploadReqInfoTest {
-
-	private UploadReqInfo createTestSubject() {
-		return new UploadReqInfo();
-	}
-
-	
-	@Test
-	public void testGetCapabilityName() throws Exception {
-		UploadReqInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCapabilityName();
-	}
-
-	
-	@Test
-	public void testSetCapabilityName() throws Exception {
-		UploadReqInfo testSubject;
-		String capabilityName = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCapabilityName(capabilityName);
-	}
-
-	
-	@Test
-	public void testGetNode() throws Exception {
-		UploadReqInfo testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getNode();
-	}
-
-	
-	@Test
-	public void testSetNode() throws Exception {
-		UploadReqInfo testSubject;
-		String node = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setNode(node);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadResourceInfoTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadResourceInfoTest.java
index a3c2e84..f4601d2 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadResourceInfoTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/UploadResourceInfoTest.java
@@ -1,13 +1,13 @@
 package org.openecomp.sdc.be.model;
 
-import java.util.LinkedList;
-import java.util.List;
-
 import org.junit.Assert;
 import org.junit.Test;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 import org.openecomp.sdc.common.api.UploadArtifactInfo;
 
+import java.util.LinkedList;
+import java.util.List;
+
 public class UploadResourceInfoTest {
 
 	private UploadResourceInfo createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCacheTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCacheTest.java
index 8e5cb5b..4868186 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCacheTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCacheTest.java
@@ -1,10 +1,7 @@
 package org.openecomp.sdc.be.model.cache;
 
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
+import fj.data.Either;
+import mockit.Deencapsulation;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.junit.Before;
 import org.junit.Test;
@@ -18,8 +15,10 @@
 import org.openecomp.sdc.be.resources.data.DataTypeData;
 import org.openecomp.sdc.be.unittests.utils.ModelConfDependentTest;
 
-import fj.data.Either;
-import mockit.Deencapsulation;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 
 public class ApplicationDataTypeCacheTest extends ModelConfDependentTest{
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ComponentCacheTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ComponentCacheTest.java
index f9a696b..49e847a 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ComponentCacheTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/ComponentCacheTest.java
@@ -1,15 +1,7 @@
 package org.openecomp.sdc.be.model.cache;
 
-import java.nio.ByteBuffer;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-
+import fj.data.Either;
+import mockit.Deencapsulation;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.ImmutableTriple;
 import org.junit.Assert;
@@ -31,654 +23,511 @@
 import org.openecomp.sdc.be.model.Resource;
 import org.openecomp.sdc.be.model.Service;
 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
-import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.resources.data.ComponentCacheData;
 import org.openecomp.sdc.be.unittests.utils.ModelConfDependentTest;
-import org.openecomp.sdc.common.util.SerializationUtils;
-import org.openecomp.sdc.common.util.ZipUtil;
 
-import fj.data.Either;
-import mockit.Deencapsulation;
+import java.util.*;
+import java.util.function.Function;
 
 public class ComponentCacheTest extends ModelConfDependentTest {
 
-	@InjectMocks
-	ComponentCache testSubject;
+    @InjectMocks
+    ComponentCache testSubject;
 
-	@Mock
-	ComponentCassandraDao componentCassandraDao;
+    @Mock
+    ComponentCassandraDao componentCassandraDao;
 
-	@Mock
-	ToscaOperationFacade toscaOperationFacade;
+    @Mock
+    ToscaOperationFacade toscaOperationFacade;
 
-	@Before
-	public void setUpMocks() throws Exception {
-		MockitoAnnotations.initMocks(this);
-	}
+    @Before
+    public void setUpMocks() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
 
-	@Test
-	public void testInit() throws Exception {
-		// default test
-		testSubject.init();
-	}
+    @Test
+    public void testInit() throws Exception {
+        // default test
+        testSubject.init();
+    }
 
-	@Test
-	public void testIsEnabled() throws Exception {
+    @Test
+    public void testIsEnabled() throws Exception {
 
-		boolean result;
+        boolean result;
 
-		// default test
+        // default test
 
-		result = testSubject.isEnabled();
-	}
+        result = testSubject.isEnabled();
+    }
 
-	@Test
-	public void testSetEnabled() throws Exception {
+    @Test
+    public void testSetEnabled() throws Exception {
 
-		boolean enabled = false;
+        boolean enabled = false;
 
-		// default test
+        // default test
 
-		testSubject.setEnabled(enabled);
-	}
+        testSubject.setEnabled(enabled);
+    }
 
-	@Test
-	public void testGetComponentNotFound() throws Exception {
+    @Test
+    public void testGetComponentNotFound() throws Exception {
 
-		String componentUid = "mock";
-		Long lastModificationTime = null;
-		Function<Component, Component> filterFieldsFunc = null;
-		Either<Component, ActionStatus> result;
+        String componentUid = "mock";
+        Long lastModificationTime = null;
+        Function<Component, Component> filterFieldsFunc = null;
+        Either<Component, ActionStatus> result;
 
-		Mockito.when(componentCassandraDao.getComponent("mock"))
-				.thenReturn(Either.right(ActionStatus.ARTIFACT_NOT_FOUND));
-		// default test
-		result = testSubject.getComponent(componentUid, lastModificationTime, filterFieldsFunc);
-	}
+        Mockito.when(componentCassandraDao.getComponent("mock"))
+                .thenReturn(Either.right(ActionStatus.ARTIFACT_NOT_FOUND));
+        // default test
+        result = testSubject.getComponent(componentUid, lastModificationTime, filterFieldsFunc);
+    }
 
-	@Test
-	public void testGetComponentInvalidDate() throws Exception {
+    @Test
+    public void testGetComponentInvalidDate() throws Exception {
 
-		String componentUid = "mock";
-		Long lastModificationTime = 0L;
-		Function<Component, Component> filterFieldsFunc = null;
-		Either<Component, ActionStatus> result;
+        String componentUid = "mock";
+        Long lastModificationTime = 0L;
+        Function<Component, Component> filterFieldsFunc = null;
+        Either<Component, ActionStatus> result;
 
-		ComponentCacheData a = new ComponentCacheData();
-		a.setModificationTime(new Date());
-		Mockito.when(componentCassandraDao.getComponent("mock")).thenReturn(Either.left(a));
-		// default test
-		result = testSubject.getComponent(componentUid, lastModificationTime, filterFieldsFunc);
-	}
+        ComponentCacheData a = new ComponentCacheData();
+        a.setModificationTime(new Date());
+        Mockito.when(componentCassandraDao.getComponent("mock")).thenReturn(Either.left(a));
+        // default test
+        result = testSubject.getComponent(componentUid, lastModificationTime, filterFieldsFunc);
+    }
 
-	@Test
-	public void testGetComponentDeserializeError() throws Exception {
+    @Test
+    public void testGetComponentDeserializeError() throws Exception {
 
-		String componentUid = "mock";
-		Long lastModificationTime = 0L;
-		Function<Component, Component> filterFieldsFunc = null;
-		Either<Component, ActionStatus> result;
+        String componentUid = "mock";
+        Long lastModificationTime = 0L;
+        Function<Component, Component> filterFieldsFunc = null;
+        Either<Component, ActionStatus> result;
 
-		ComponentCacheData a = new ComponentCacheData();
-		a.setModificationTime(new Date(0L));
-		a.setType(NodeTypeEnum.Resource.getName());
-		Mockito.when(componentCassandraDao.getComponent("mock")).thenReturn(Either.left(a));
-		// default test
-		result = testSubject.getComponent(componentUid, lastModificationTime, filterFieldsFunc);
-	}
+        ComponentCacheData a = new ComponentCacheData();
+        a.setModificationTime(new Date(0L));
+        a.setType(NodeTypeEnum.Resource.getName());
+        Mockito.when(componentCassandraDao.getComponent("mock")).thenReturn(Either.left(a));
+        // default test
+        result = testSubject.getComponent(componentUid, lastModificationTime, filterFieldsFunc);
+    }
 
-	@Test
-	public void testGetComponent() throws Exception {
+    @Test
+    public void testGetAllComponentIdTimeAndType() throws Exception {
 
-		String componentUid = "mock";
-		Long lastModificationTime = 0L;
-		Function<Component, Component> filterFieldsFunc = null;
-		Either<Component, ActionStatus> result;
+        Either<List<ComponentCacheData>, ActionStatus> result;
 
-		ComponentCacheData a = new ComponentCacheData();
-		a.setModificationTime(new Date(0L));
-		a.setType(NodeTypeEnum.Resource.getName());
-		Resource resource = new Resource();
-		Either<byte[], Boolean> serialize = SerializationUtils.serializeExt(resource);
-		byte[] value = serialize.left().value();
-		a.setData(ByteBuffer.wrap(value));
-		Mockito.when(componentCassandraDao.getComponent("mock")).thenReturn(Either.left(a));
-		// default test
-		result = testSubject.getComponent(componentUid, lastModificationTime, filterFieldsFunc);
-	}
+        // default test
 
-	@Test
-	public void testGetAllComponentIdTimeAndType() throws Exception {
+        result = testSubject.getAllComponentIdTimeAndType();
+        testSubject.setEnabled(false);
+        result = testSubject.getAllComponentIdTimeAndType();
+    }
 
-		Either<List<ComponentCacheData>, ActionStatus> result;
+    @Test
+    public void testUpdateCatalogInMemoryCacheWithCertified() throws Exception {
 
-		// default test
+        List<Component> foundComponents = new LinkedList<>();
 
-		result = testSubject.getAllComponentIdTimeAndType();
-		testSubject.setEnabled(false);
-		result = testSubject.getAllComponentIdTimeAndType();
-	}
+        // default test
+        testSubject.init();
+        Deencapsulation.invoke(testSubject, "updateCatalogInMemoryCacheWithCertified", foundComponents,
+                ComponentTypeEnum.RESOURCE);
+    }
 
-	@Test
-	public void testUpdateCatalogInMemoryCacheWithCertified() throws Exception {
+    @Test
+    public void testGetDataFromInMemoryCache() throws Exception {
 
-		List<Component> foundComponents = new LinkedList<>();
+        Set<String> components = new HashSet<>();
+        components.add("mock");
+        ComponentTypeEnum componentTypeEnum = null;
+        List<Component> result;
 
-		// default test
-		testSubject.init();
-		Deencapsulation.invoke(testSubject, "updateCatalogInMemoryCacheWithCertified", foundComponents,
-				ComponentTypeEnum.RESOURCE);
-	}
+        // default test
+        testSubject.init();
+        result = Deencapsulation.invoke(testSubject, "getDataFromInMemoryCache", components,
+                ComponentTypeEnum.RESOURCE);
+    }
 
-	@Test
-	public void testGetDataFromInMemoryCache() throws Exception {
+    @Test
+    public void testGetComponents() throws Exception {
 
-		Set<String> components = new HashSet<>();
-		components.add("mock");
-		ComponentTypeEnum componentTypeEnum = null;
-		List<Component> result;
+        Set<String> components = new HashSet<>();
+        Function<List<Component>, List<Component>> filterFieldsFunc = new Function<List<Component>, List<Component>>() {
 
-		// default test
-		testSubject.init();
-		result = Deencapsulation.invoke(testSubject, "getDataFromInMemoryCache", components,
-				ComponentTypeEnum.RESOURCE);
-	}
+            @Override
+            public List<Component> apply(List<Component> t) {
+                return t;
+            }
+        };
+        Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
 
-	@Test
-	public void testGetComponents() throws Exception {
+        List<ComponentCacheData> list = new LinkedList<>();
+        Mockito.when(componentCassandraDao.getComponents(Mockito.any(List.class))).thenReturn(Either.left(list));
 
-		Set<String> components = new HashSet<>();
-		Function<List<Component>, List<Component>> filterFieldsFunc = new Function<List<Component>, List<Component>>() {
+        // default test
+        testSubject.init();
+        result = testSubject.getComponents(components, filterFieldsFunc);
+    }
 
-			@Override
-			public List<Component> apply(List<Component> t) {
-				return t;
-			}
-		};
-		Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
+    @Test
+    public void testGetComponentsNotAllowed() throws Exception {
 
-		List<ComponentCacheData> list = new LinkedList<>();
-		Mockito.when(componentCassandraDao.getComponents(Mockito.any(List.class))).thenReturn(Either.left(list));
+        Set<String> components = new HashSet<>();
+        Function<List<Component>, List<Component>> filterFieldsFunc = null;
 
-		// default test
-		testSubject.init();
-		result = testSubject.getComponents(components, filterFieldsFunc);
-	}
+        Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
 
-	@Test
-	public void testGetComponentsNotAllowed() throws Exception {
+        // default test
+        testSubject.setEnabled(false);
+        result = testSubject.getComponents(components, filterFieldsFunc);
+    }
 
-		Set<String> components = new HashSet<>();
-		Function<List<Component>, List<Component>> filterFieldsFunc = null;
+    @Test
+    public void testGetComponentsCassndraError() throws Exception {
 
-		Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
+        Set<String> components = new HashSet<>();
+        Function<List<Component>, List<Component>> filterFieldsFunc = null;
+        Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
 
-		// default test
-		testSubject.setEnabled(false);
-		result = testSubject.getComponents(components, filterFieldsFunc);
-	}
+        Mockito.when(componentCassandraDao.getComponents(Mockito.any(List.class)))
+                .thenReturn(Either.right(ActionStatus.GENERAL_ERROR));
 
-	@Test
-	public void testGetComponentsCassndraError() throws Exception {
+        // default test
+        testSubject.init();
+        result = testSubject.getComponents(components, filterFieldsFunc);
+    }
 
-		Set<String> components = new HashSet<>();
-		Function<List<Component>, List<Component>> filterFieldsFunc = null;
-		Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
+    @Test
+    public void testGetComponentsForLeftPanel() throws Exception {
 
-		Mockito.when(componentCassandraDao.getComponents(Mockito.any(List.class)))
-				.thenReturn(Either.right(ActionStatus.GENERAL_ERROR));
+        ComponentTypeEnum componentTypeEnum = null;
+        String internalComponentType = "mock";
+        Set<String> filteredResources = new HashSet<>();
+        Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
 
-		// default test
-		testSubject.init();
-		result = testSubject.getComponents(components, filterFieldsFunc);
-	}
+        List<ComponentCacheData> list = new LinkedList<>();
+        Mockito.when(componentCassandraDao.getComponents(Mockito.any(List.class))).thenReturn(Either.left(list));
 
-	@Test
-	public void testGetComponentsForLeftPanel() throws Exception {
+        // default test
+        result = testSubject.getComponentsForLeftPanel(ComponentTypeEnum.RESOURCE, internalComponentType,
+                filteredResources);
+    }
 
-		ComponentTypeEnum componentTypeEnum = null;
-		String internalComponentType = "mock";
-		Set<String> filteredResources = new HashSet<>();
-		Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
+    @Test
+    public void testFilterForLeftPanel() throws Exception {
 
-		List<ComponentCacheData> list = new LinkedList<>();
-		Mockito.when(componentCassandraDao.getComponents(Mockito.any(List.class))).thenReturn(Either.left(list));
+        List<Component> components = new LinkedList<>();
+        List<Component> result;
 
-		// default test
-		result = testSubject.getComponentsForLeftPanel(ComponentTypeEnum.RESOURCE, internalComponentType,
-				filteredResources);
-	}
+        // test 1
 
-	@Test
-	public void testFilterForLeftPanel() throws Exception {
+        result = Deencapsulation.invoke(testSubject, "filterForLeftPanel", components);
+        Assert.assertNotEquals(null, result);
+    }
 
-		List<Component> components = new LinkedList<>();
-		List<Component> result;
+    @Test
+    public void testFilterForCatalog() throws Exception {
 
-		// test 1
+        List<Component> components = new LinkedList<>();
+        List<Component> result;
 
-		result = Deencapsulation.invoke(testSubject, "filterForLeftPanel", components);
-		Assert.assertNotEquals(null, result);
-	}
+        // test 1
+        result = Deencapsulation.invoke(testSubject, "filterForCatalog", components);
+        Assert.assertNotEquals(null, result);
+    }
 
-	@Test
-	public void testFilterForCatalog() throws Exception {
+    @Test
+    public void testFilterFieldsForLeftPanel() throws Exception {
+        Component result;
 
-		List<Component> components = new LinkedList<>();
-		List<Component> result;
+        // default test
+        Resource resource = new Resource();
+        resource.setComponentType(ComponentTypeEnum.RESOURCE);
+        result = Deencapsulation.invoke(testSubject, "filterFieldsForLeftPanel", resource);
+        Service service = new Service();
+        service.setComponentType(ComponentTypeEnum.SERVICE);
+        result = Deencapsulation.invoke(testSubject, "filterFieldsForLeftPanel", service);
+    }
 
-		// test 1
-		result = Deencapsulation.invoke(testSubject, "filterForCatalog", components);
-		Assert.assertNotEquals(null, result);
-	}
+    @Test
+    public void testFilterFieldsForCatalog() throws Exception {
+        Component result;
 
-	@Test
-	public void testFilterFieldsForLeftPanel() throws Exception {
-		Component result;
+        // default test
 
-		// default test
-		result = Deencapsulation.invoke(testSubject, "filterFieldsForLeftPanel", new Resource());
-		result = Deencapsulation.invoke(testSubject, "filterFieldsForLeftPanel", new Service());
-	}
+        Resource resource = new Resource();
+        resource.setComponentType(ComponentTypeEnum.RESOURCE);
+        result = Deencapsulation.invoke(testSubject, "filterFieldsForCatalog", resource);
+        Service service = new Service();
+        service.setComponentType(ComponentTypeEnum.SERVICE);
+        result = Deencapsulation.invoke(testSubject, "filterFieldsForCatalog", service);
+        Product product = new Product();
+        product.setComponentType(ComponentTypeEnum.PRODUCT);
+        result = Deencapsulation.invoke(testSubject, "filterFieldsForCatalog", product);
+    }
 
-	@Test
-	public void testFilterFieldsForCatalog() throws Exception {
-		Component result;
+    @Test
+    public void testCopyFieldsForLeftPanel() throws Exception {
 
-		// default test
-		result = Deencapsulation.invoke(testSubject, "filterFieldsForCatalog", new Resource());
-		result = Deencapsulation.invoke(testSubject, "filterFieldsForCatalog", new Service());
-		result = Deencapsulation.invoke(testSubject, "filterFieldsForCatalog", new Product());
-	}
+        Component component = new Resource();
+        Component filteredComponent = new Resource();
+        ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition())
+                .setResourceType(ResourceTypeEnum.VL);
+        // default test
 
-	@Test
-	public void testCopyFieldsForLeftPanel() throws Exception {
+        Deencapsulation.invoke(testSubject, "copyFieldsForLeftPanel", component, filteredComponent);
+    }
 
-		Component component = new Resource();
-		Component filteredComponent = new Resource();
-		((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition())
-				.setResourceType(ResourceTypeEnum.VL);
-		// default test
+    @Test
+    public void testGetComponentsFullDisabled() throws Exception {
 
-		Deencapsulation.invoke(testSubject, "copyFieldsForLeftPanel", component, filteredComponent);
-	}
+        Set<String> filteredResources = null;
+        Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
 
-	@Test
-	public void testGetComponentsFullDisabled() throws Exception {
+        // default test
+        testSubject.setEnabled(false);
+        result = Deencapsulation.invoke(testSubject, "getComponentsFull", Set.class);
+    }
 
-		Set<String> filteredResources = null;
-		Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
 
-		// default test
-		testSubject.setEnabled(false);
-		result = Deencapsulation.invoke(testSubject, "getComponentsFull", Set.class);
-	}
+    @Test
+    public void testGetComponentsFullDesirializeError() throws Exception {
 
-	@Test
-	public void testGetComponentsFull() throws Exception {
+        Set<String> filteredResources = new HashSet<>();
+        filteredResources.add("mock");
+        Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
 
-		Set<String> filteredResources = new HashSet<>();
-		filteredResources.add("mock");
-		Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
+        List<ComponentCacheData> a = new LinkedList<>();
+        ComponentCacheData e = new ComponentCacheData();
+        e.setId("mock");
+        e.setType(NodeTypeEnum.Resource.getName());
+        a.add(e);
+        Mockito.when(componentCassandraDao.getComponents(Mockito.any(List.class))).thenReturn(Either.left(a));
 
-		List<ComponentCacheData> a = new LinkedList<>();
-		ComponentCacheData e = new ComponentCacheData();
-		e.setId("mock");
-		e.setType(NodeTypeEnum.Resource.getName());
-		Resource resource = new Resource();
-		Either<byte[], Boolean> serialize = SerializationUtils.serializeExt(resource);
-		byte[] value = serialize.left().value();
-		e.setData(ByteBuffer.wrap(value));
-		a.add(e);
-		Mockito.when(componentCassandraDao.getComponents(Mockito.any(List.class))).thenReturn(Either.left(a));
+        // default test
 
-		// default test
+        result = Deencapsulation.invoke(testSubject, "getComponentsFull", filteredResources);
+    }
 
-		result = Deencapsulation.invoke(testSubject, "getComponentsFull", filteredResources);
-	}
 
-	@Test
-	public void testGetComponentsFullDesirializeError() throws Exception {
+    @Test
+    public void testGetComponent_1() throws Exception {
 
-		Set<String> filteredResources = new HashSet<>();
-		filteredResources.add("mock");
-		Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result;
+        String componentUid = "mock";
+        Either<Component, ActionStatus> result;
 
-		List<ComponentCacheData> a = new LinkedList<>();
-		ComponentCacheData e = new ComponentCacheData();
-		e.setId("mock");
-		e.setType(NodeTypeEnum.Resource.getName());
-		a.add(e);
-		Mockito.when(componentCassandraDao.getComponents(Mockito.any(List.class))).thenReturn(Either.left(a));
-
-		// default test
-
-		result = Deencapsulation.invoke(testSubject, "getComponentsFull", filteredResources);
-	}
-
-	@Test
-	public void testConvertComponentCacheToComponentServiceZipped() throws Exception {
-
-		ComponentCacheData componentCacheData = new ComponentCacheData();
-		Either<? extends Component, Boolean> result;
-
-		componentCacheData.setId("mock");
-		componentCacheData.setType(NodeTypeEnum.Service.getName());
-		componentCacheData.setIsZipped(true);
-		Service service = new Service();
-		Either<byte[], Boolean> serialize = SerializationUtils.serializeExt(service);
-		byte[] value = serialize.left().value();
-
-		componentCacheData.setData(ByteBuffer.wrap(ZipUtil.zipBytes(value)));
-
-		// default test
-
-		result = Deencapsulation.invoke(testSubject, "convertComponentCacheToComponent", componentCacheData);
-	}
-
-	@Test
-	public void testConvertComponentCacheToComponentProductZipped() throws Exception {
-
-		ComponentCacheData componentCacheData = new ComponentCacheData();
-		Either<? extends Component, Boolean> result;
-
-		componentCacheData.setId("mock");
-		componentCacheData.setType(NodeTypeEnum.Product.getName());
-		componentCacheData.setIsZipped(true);
-		Product product = new Product();
-		Either<byte[], Boolean> serialize = SerializationUtils.serializeExt(product);
-		byte[] value = serialize.left().value();
-
-		componentCacheData.setData(ByteBuffer.wrap(ZipUtil.zipBytes(value)));
-
-		// default test
-
-		result = Deencapsulation.invoke(testSubject, "convertComponentCacheToComponent", componentCacheData);
-	}
-
-	@Test
-	public void testGetComponent_1() throws Exception {
-
-		String componentUid = "mock";
-		Either<Component, ActionStatus> result;
-
-		Mockito.when(componentCassandraDao.getComponent("mock"))
-				.thenReturn(Either.right(ActionStatus.ARTIFACT_NOT_FOUND));
-
-		// default test
-		result = testSubject.getComponent(componentUid);
-	}
-
-	@Test
-	public void testGetComponent_2() throws Exception {
+        Mockito.when(componentCassandraDao.getComponent("mock"))
+                .thenReturn(Either.right(ActionStatus.ARTIFACT_NOT_FOUND));
 
-		String componentUid = "mock";
-		Long lastModificationTime = null;
-		Either<Component, ActionStatus> result;
+        // default test
+        result = testSubject.getComponent(componentUid);
+    }
 
-		Mockito.when(componentCassandraDao.getComponent("mock"))
-				.thenReturn(Either.right(ActionStatus.ARTIFACT_NOT_FOUND));
+    @Test
+    public void testGetComponent_2() throws Exception {
 
-		// default test
+        String componentUid = "mock";
+        Long lastModificationTime = null;
+        Either<Component, ActionStatus> result;
 
-		result = testSubject.getComponent(componentUid, lastModificationTime);
-	}
+        Mockito.when(componentCassandraDao.getComponent("mock"))
+                .thenReturn(Either.right(ActionStatus.ARTIFACT_NOT_FOUND));
 
-	@Test
-	public void testSetComponentDisabled() throws Exception {
+        // default test
+        Function<Component, Component> filterFieldsFunc = new Function<Component, Component>() {
+            @Override
+            public Component apply(Component component) {
+                return new Resource();
+            }
+        };
+        result = testSubject.getComponent(componentUid, lastModificationTime, filterFieldsFunc);
+    }
 
-		String componentUid = "";
-		Long lastModificationTime = null;
-		NodeTypeEnum nodeTypeEnum = null;
-		boolean result;
+    @Test
+    public void testSaveComponent() throws Exception {
 
-		// default test
-		testSubject.setEnabled(false);
-		result = testSubject.setComponent(componentUid, lastModificationTime, nodeTypeEnum);
-	}
+        String componentUid = "";
+        Component component = new Resource();
+        boolean result;
 
-	@Test
-	public void testSetComponentNotFound() throws Exception {
+        // default test
+        Mockito.when(componentCassandraDao.saveComponent(Mockito.any(ComponentCacheData.class)))
+                .thenReturn(CassandraOperationStatus.OK);
 
-		String componentUid = "";
-		Long lastModificationTime = null;
-		boolean result;
+        result = Deencapsulation.invoke(testSubject, "saveComponent", componentUid, 0L, NodeTypeEnum.Resource,
+                component);
+    }
 
-		// default test
-		Mockito.when(toscaOperationFacade.getToscaElement(componentUid))
-				.thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+    @Test
+    public void testSetComponent_1Disabled() throws Exception {
 
-		result = testSubject.setComponent(componentUid, lastModificationTime, NodeTypeEnum.Resource);
-	}
+        Component component = new Resource();
+        component.setLastUpdateDate(0L);
+        boolean result;
 
-	@Test
-	public void testSetComponent() throws Exception {
+        // default test
+        testSubject.setEnabled(false);
+        result = testSubject.setComponent(component, NodeTypeEnum.Resource);
+    }
 
-		String componentUid = "";
-		Long lastModificationTime = 0L;
-		boolean result;
+    @Test
+    public void testSetComponent_1() throws Exception {
 
-		// default test
-		Mockito.when(toscaOperationFacade.getToscaElement(componentUid)).thenReturn(Either.left(new Resource()));
+        Component component = new Resource();
+        component.setLastUpdateDate(0L);
+        boolean result;
 
-		result = testSubject.setComponent(componentUid, lastModificationTime, NodeTypeEnum.Resource);
-	}
+        // default test
 
-	@Test
-	public void testSaveComponent() throws Exception {
+        result = testSubject.setComponent(component, NodeTypeEnum.Resource);
+    }
 
-		String componentUid = "";
-		Component component = new Resource();
-		boolean result;
 
-		// default test
-		Mockito.when(componentCassandraDao.saveComponent(Mockito.any(ComponentCacheData.class)))
-				.thenReturn(CassandraOperationStatus.OK);
+    @Test
+    public void testGetComponentsFull_1CannotDeserialize() throws Exception {
+        Map<String, Long> filteredResources = new HashMap<>();
+        Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
 
-		result = Deencapsulation.invoke(testSubject, "saveComponent", componentUid, 0L, NodeTypeEnum.Resource,
-				component);
-	}
+        // default test
+        LinkedList<ComponentCacheData> left = new LinkedList<>();
+        ComponentCacheData e = new ComponentCacheData();
+        e.setType(NodeTypeEnum.Resource.getName());
+        left.add(e);
+        ImmutablePair<List<ComponentCacheData>, Set<String>> immutablePair = ImmutablePair.of(left, new HashSet<>());
+        Mockito.when(componentCassandraDao.getComponents(Mockito.any(Map.class))).thenReturn(Either.left(immutablePair));
 
-	@Test
-	public void testSetComponent_1Disabled() throws Exception {
+        result = Deencapsulation.invoke(testSubject, "getComponentsFull", filteredResources);
+    }
 
-		Component component = new Resource();
-		component.setLastUpdateDate(0L);
-		boolean result;
+    @Test
+    public void testGetComponentsFull_1Disabled() throws Exception {
+        Map<String, Long> filteredResources = new HashMap<>();
+        Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
 
-		// default test
-		testSubject.setEnabled(false);
-		result = testSubject.setComponent(component, NodeTypeEnum.Resource);
-	}
+        // default test
+        testSubject.setEnabled(false);
+        result = Deencapsulation.invoke(testSubject, "getComponentsFull", filteredResources);
+    }
 
-	@Test
-	public void testSetComponent_1() throws Exception {
+    @Test
+    public void testGetComponentsFull_1NotFound() throws Exception {
+        Map<String, Long> filteredResources = new HashMap<>();
+        Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
 
-		Component component = new Resource();
-		component.setLastUpdateDate(0L);
-		boolean result;
+        // default test
+        Mockito.when(componentCassandraDao.getComponents(Mockito.any(Map.class))).thenReturn(Either.right(ActionStatus.ARTIFACT_NOT_FOUND));
 
-		// default test
+        result = Deencapsulation.invoke(testSubject, "getComponentsFull", filteredResources);
+    }
 
-		result = testSubject.setComponent(component, NodeTypeEnum.Resource);
-	}
+    @Test
+    public void testGetComponentsForCatalog_1Disabled() throws Exception {
 
-	@Test
-	public void testGetComponentsFull_1() throws Exception {
-		Map<String, Long> filteredResources = new HashMap<>();
-		Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
+        Map<String, Long> components = null;
+        Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
 
-		// default test
-		LinkedList<ComponentCacheData> left = new LinkedList<>();
-		ComponentCacheData e = new ComponentCacheData();
-		Either<byte[], Boolean> serializeExt = SerializationUtils.serializeExt(new Resource());
-		e.setData(ByteBuffer.wrap(serializeExt.left().value()));
-		e.setType(NodeTypeEnum.Resource.getName());
-		left.add(e);
-		ImmutablePair<List<ComponentCacheData>, Set<String>> immutablePair = ImmutablePair.of(left, new HashSet<>());
-		Mockito.when(componentCassandraDao.getComponents(Mockito.any(Map.class))).thenReturn(Either.left(immutablePair));
-		
-		result = Deencapsulation.invoke(testSubject, "getComponentsFull", filteredResources);
-	}
-	
-	@Test
-	public void testGetComponentsFull_1CannotDeserialize() throws Exception {
-		Map<String, Long> filteredResources = new HashMap<>();
-		Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
+        // default test
+        testSubject.setEnabled(false);
+        result = testSubject.getComponentsForCatalog(components, ComponentTypeEnum.RESOURCE);
+    }
 
-		// default test
-		LinkedList<ComponentCacheData> left = new LinkedList<>();
-		ComponentCacheData e = new ComponentCacheData();
-		e.setType(NodeTypeEnum.Resource.getName());
-		left.add(e);
-		ImmutablePair<List<ComponentCacheData>, Set<String>> immutablePair = ImmutablePair.of(left, new HashSet<>());
-		Mockito.when(componentCassandraDao.getComponents(Mockito.any(Map.class))).thenReturn(Either.left(immutablePair));
-		
-		result = Deencapsulation.invoke(testSubject, "getComponentsFull", filteredResources);
-	}
-	
-	@Test
-	public void testGetComponentsFull_1Disabled() throws Exception {
-		Map<String, Long> filteredResources = new HashMap<>();
-		Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
+    @Test
+    public void testGetComponentsForCatalog_1() throws Exception {
+        Map<String, Long> components = new HashMap<>();
+        Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
 
-		// default test
-		testSubject.setEnabled(false);
-		result = Deencapsulation.invoke(testSubject, "getComponentsFull", filteredResources);
-	}
-	
-	@Test
-	public void testGetComponentsFull_1NotFound() throws Exception {
-		Map<String, Long> filteredResources = new HashMap<>();
-		Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
+        // default test
+        ImmutablePair<List<ComponentCacheData>, Set<String>> value = ImmutablePair.of(new LinkedList<>(), new HashSet<>());
+        Mockito.when(componentCassandraDao.getComponents(Mockito.any(Map.class))).thenReturn(Either.left(value));
+        testSubject.init();
+        result = testSubject.getComponentsForCatalog(components, ComponentTypeEnum.RESOURCE);
+    }
 
-		// default test
-		Mockito.when(componentCassandraDao.getComponents(Mockito.any(Map.class))).thenReturn(Either.right(ActionStatus.ARTIFACT_NOT_FOUND));
-		
-		result = Deencapsulation.invoke(testSubject, "getComponentsFull", filteredResources);
-	}
-	
-	@Test
-	public void testGetComponentsForCatalog_1Disabled() throws Exception {
+    @Test
+    public void testGetComponentsForCatalog_1Error() throws Exception {
+        Map<String, Long> components = new HashMap<>();
+        Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
 
-		Map<String, Long> components = null;
-		Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
+        // default test
+        Mockito.when(componentCassandraDao.getComponents(Mockito.any(Map.class))).thenReturn(Either.right(ActionStatus.COMPONENT_NOT_FOUND));
 
-		// default test
-		testSubject.setEnabled(false);
-		result = testSubject.getComponentsForCatalog(components, ComponentTypeEnum.RESOURCE);
-	}
-	
-	@Test
-	public void testGetComponentsForCatalog_1() throws Exception {
-		Map<String, Long> components = new HashMap<>();
-		Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
+        result = testSubject.getComponentsForCatalog(components, ComponentTypeEnum.RESOURCE);
+    }
 
-		// default test
-		ImmutablePair<List<ComponentCacheData>, Set<String>> value = ImmutablePair.of(new LinkedList<>(), new HashSet<>()); 
-		Mockito.when(componentCassandraDao.getComponents(Mockito.any(Map.class))).thenReturn(Either.left(value));
-		testSubject.init();
-		result = testSubject.getComponentsForCatalog(components, ComponentTypeEnum.RESOURCE);
-	}
-	
-	@Test
-	public void testGetComponentsForCatalog_1Error() throws Exception {
-		Map<String, Long> components = new HashMap<>();
-		Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
+    @Test
+    public void testGetComponents_1Disabled() throws Exception {
 
-		// default test
-		Mockito.when(componentCassandraDao.getComponents(Mockito.any(Map.class))).thenReturn(Either.right(ActionStatus.COMPONENT_NOT_FOUND));
-		
-		result = testSubject.getComponentsForCatalog(components, ComponentTypeEnum.RESOURCE);
-	}
-	
-	@Test
-	public void testGetComponents_1Disabled() throws Exception {
+        Map<String, Long> components = null;
+        Function<List<Component>, List<Component>> filterFieldsFunc = null;
+        Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
 
-		Map<String, Long> components = null;
-		Function<List<Component>, List<Component>> filterFieldsFunc = null;
-		Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result;
+        // default test
+        testSubject.setEnabled(false);
+        result = testSubject.getComponents(components, filterFieldsFunc);
+    }
 
-		// default test
-		testSubject.setEnabled(false);
-		result = testSubject.getComponents(components, filterFieldsFunc);
-	}
+    @Test
+    public void testGetComponentAndTimeNotFound() throws Exception {
 
-	@Test
-	public void testGetComponentAndTime() throws Exception {
+        String componentUid = "";
+        Function<Component, Component> filterFieldsFunc = null;
+        Either<ImmutablePair<Component, Long>, ActionStatus> result;
 
-		String componentUid = "";
-		Function<Component, Component> filterFieldsFunc = null;
-		Either<ImmutablePair<Component, Long>, ActionStatus> result;
+        // default test
+        Mockito.when(componentCassandraDao.getComponent(Mockito.anyString())).thenReturn(Either.right(ActionStatus.API_RESOURCE_NOT_FOUND));
 
-		// default test
-		ComponentCacheData a = new ComponentCacheData();
-		a.setModificationTime(new Date());
-		a.setType(NodeTypeEnum.Resource.getName());
-		Either<byte[], Boolean> serializeExt = SerializationUtils.serializeExt(new Resource());
-		a.setData(ByteBuffer.wrap(serializeExt.left().value()));
-		Mockito.when(componentCassandraDao.getComponent(Mockito.anyString())).thenReturn(Either.left(a));
-		
-		result = testSubject.getComponentAndTime(componentUid, filterFieldsFunc);
-	}
+        result = testSubject.getComponentAndTime(componentUid, filterFieldsFunc);
+    }
 
-	@Test
-	public void testGetComponentAndTimeNotFound() throws Exception {
+    @Test
+    public void testGetComponentFromCacheDisabled() throws Exception {
+        String componentUid = "";
+        Long lastModificationTime = null;
+        Function<Component, Component> filterFieldsFunc = null;
+        Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> result;
 
-		String componentUid = "";
-		Function<Component, Component> filterFieldsFunc = null;
-		Either<ImmutablePair<Component, Long>, ActionStatus> result;
+        // test 1
+        lastModificationTime = null;
+        testSubject.setEnabled(false);
+        result = Deencapsulation.invoke(testSubject, "getComponentFromCache",
+                new Object[]{componentUid, Long.class, Function.class});
+    }
 
-		// default test
-		Mockito.when(componentCassandraDao.getComponent(Mockito.anyString())).thenReturn(Either.right(ActionStatus.API_RESOURCE_NOT_FOUND));
-		
-		result = testSubject.getComponentAndTime(componentUid, filterFieldsFunc);
-	}
-	
-	@Test
-	public void testGetComponentFromCacheDisabled() throws Exception {
-		String componentUid = "";
-		Long lastModificationTime = null;
-		Function<Component, Component> filterFieldsFunc = null;
-		Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> result;
+    @Test
+    public void testDeleteComponentFromCacheFails() throws Exception {
 
-		// test 1
-		lastModificationTime = null;
-		testSubject.setEnabled(false);
-		result = Deencapsulation.invoke(testSubject, "getComponentFromCache",
-				new Object[] { componentUid, Long.class, Function.class });
-	}
+        String id = "";
+        ActionStatus result;
 
-	@Test
-	public void testDeleteComponentFromCacheFails() throws Exception {
+        // default test
 
-		String id = "";
-		ActionStatus result;
+        result = testSubject.deleteComponentFromCache(id);
+    }
 
-		// default test
+    @Test
+    public void testDeleteComponentFromCacheDisabled() throws Exception {
 
-		result = testSubject.deleteComponentFromCache(id);
-	}
-	
-	@Test
-	public void testDeleteComponentFromCacheDisabled() throws Exception {
+        String id = "";
+        ActionStatus result;
 
-		String id = "";
-		ActionStatus result;
+        // default test
+        testSubject.setEnabled(false);
+        result = testSubject.deleteComponentFromCache(id);
+    }
 
-		// default test
-		testSubject.setEnabled(false);
-		result = testSubject.deleteComponentFromCache(id);
-	}
-	
-	@Test
-	public void testDeleteComponentFromCache() throws Exception {
+    @Test
+    public void testDeleteComponentFromCache() throws Exception {
 
-		String id = "";
-		ActionStatus result;
+        String id = "";
+        ActionStatus result;
 
-		// default test
-		Mockito.when(componentCassandraDao.deleteComponent(Mockito.anyString())).thenReturn(CassandraOperationStatus.OK);
-		result = testSubject.deleteComponentFromCache(id);
-	}
+        // default test
+        Mockito.when(componentCassandraDao.deleteComponent(Mockito.anyString())).thenReturn(CassandraOperationStatus.OK);
+        result = testSubject.deleteComponentFromCache(id);
+    }
 }
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJobTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJobTest.java
index 148e237..5347bc0 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJobTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJobTest.java
@@ -1,7 +1,7 @@
 package org.openecomp.sdc.be.model.cache.jobs;
 
-import java.util.function.Function;
-
+import fj.data.Either;
+import mockit.Deencapsulation;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.junit.Before;
 import org.junit.Test;
@@ -19,8 +19,7 @@
 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
 
-import fj.data.Either;
-import mockit.Deencapsulation;
+import java.util.function.Function;
 
 public class CheckAndUpdateJobTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/category/CategoryDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/category/CategoryDefinitionTest.java
deleted file mode 100644
index cac17ef..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/category/CategoryDefinitionTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.openecomp.sdc.be.model.category;
-
-import java.util.List;
-
-import org.junit.Test;
-
-
-public class CategoryDefinitionTest {
-
-	private CategoryDefinition createTestSubject() {
-		return new CategoryDefinition();
-	}
-
-	
-	@Test
-	public void testGetSubcategories() throws Exception {
-		CategoryDefinition testSubject;
-		List<SubCategoryDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getSubcategories();
-	}
-
-	
-	@Test
-	public void testSetSubcategories() throws Exception {
-		CategoryDefinition testSubject;
-		List<SubCategoryDefinition> subcategories = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setSubcategories(subcategories);
-	}
-
-	
-	@Test
-	public void testAddSubCategory() throws Exception {
-		CategoryDefinition testSubject;
-		SubCategoryDefinition subcategory = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.addSubCategory(subcategory);
-	}
-
-	
-	@Test
-	public void testToString() throws Exception {
-		CategoryDefinition testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.toString();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/category/SubCategoryDefinitionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/category/SubCategoryDefinitionTest.java
deleted file mode 100644
index 4349ca2..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/category/SubCategoryDefinitionTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.openecomp.sdc.be.model.category;
-
-import java.util.List;
-
-import org.junit.Test;
-
-
-public class SubCategoryDefinitionTest {
-
-	private SubCategoryDefinition createTestSubject() {
-		return new SubCategoryDefinition();
-	}
-
-	
-	@Test
-	public void testGetGroupings() throws Exception {
-		SubCategoryDefinition testSubject;
-		List<GroupingDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getGroupings();
-	}
-
-	
-	@Test
-	public void testSetGroupings() throws Exception {
-		SubCategoryDefinition testSubject;
-		List<GroupingDefinition> groupingDefinitions = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setGroupings(groupingDefinitions);
-	}
-
-	
-	@Test
-	public void testAddGrouping() throws Exception {
-		SubCategoryDefinition testSubject;
-		GroupingDefinition groupingDefinition = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.addGrouping(groupingDefinition);
-	}
-
-	
-	@Test
-	public void testToString() throws Exception {
-		SubCategoryDefinition testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.toString();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ModelOperationsSpringConfig.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ModelOperationsSpringConfig.java
index 1215b5f..e7210d4 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ModelOperationsSpringConfig.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ModelOperationsSpringConfig.java
@@ -4,6 +4,6 @@
 import org.springframework.context.annotation.Configuration;
 
 @Configuration
-@ComponentScan({"org.openecomp.sdc.be.model.jsontitan.operations","org.openecomp.sdc.be.model.jsontitan.utils"})
+@ComponentScan({"org.openecomp.sdc.be.dao.cassandra","org.openecomp.sdc.be.model.cache","org.openecomp.sdc.be.model.jsontitan.operations","org.openecomp.sdc.be.model.jsontitan.utils", "org.openecomp.sdc.be.model.operations.impl"})
 public class ModelOperationsSpringConfig {
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeTypeTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeTypeTest.java
deleted file mode 100644
index aae9d6f..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeTypeTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package org.openecomp.sdc.be.model.jsontitan.datamodel;
-
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
-
-
-public class NodeTypeTest {
-
-	private NodeType createTestSubject() {
-		return new NodeType();
-	}
-
-	
-	@Test
-	public void testGetDerivedList() throws Exception {
-		NodeType testSubject;
-		List<String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getDerivedList();
-	}
-
-	
-	@Test
-	public void testSetDerivedList() throws Exception {
-		NodeType testSubject;
-		List<String> derivedList = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setDerivedList(derivedList);
-	}
-
-	
-	@Test
-	public void testGetDerivedFrom() throws Exception {
-		NodeType testSubject;
-		List<String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getDerivedFrom();
-	}
-
-	
-	@Test
-	public void testSetDerivedFrom() throws Exception {
-		NodeType testSubject;
-		List<String> derivedFrom = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setDerivedFrom(derivedFrom);
-	}
-
-	
-	@Test
-	public void testGetAttributes() throws Exception {
-		NodeType testSubject;
-		Map<String, PropertyDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getAttributes();
-	}
-
-	
-	@Test
-	public void testSetAttributes() throws Exception {
-		NodeType testSubject;
-		Map<String, PropertyDataDefinition> attributes = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setAttributes(attributes);
-	}
-
-	
-	@Test
-	public void testGetCapabilties() throws Exception {
-		NodeType testSubject;
-		Map<String, ListCapabilityDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCapabilties();
-	}
-
-	
-	@Test
-	public void testSetCapabilties() throws Exception {
-		NodeType testSubject;
-		Map<String, ListCapabilityDataDefinition> capabilties = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCapabilties(capabilties);
-	}
-
-	
-	@Test
-	public void testGetRequirements() throws Exception {
-		NodeType testSubject;
-		Map<String, ListRequirementDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getRequirements();
-	}
-
-	
-	@Test
-	public void testSetRequirements() throws Exception {
-		NodeType testSubject;
-		Map<String, ListRequirementDataDefinition> requirements = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setRequirements(requirements);
-	}
-
-	
-	@Test
-	public void testGetCapabiltiesProperties() throws Exception {
-		NodeType testSubject;
-		Map<String, MapPropertiesDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCapabiltiesProperties();
-	}
-
-	
-	@Test
-	public void testSetCapabiltiesProperties() throws Exception {
-		NodeType testSubject;
-		Map<String, MapPropertiesDataDefinition> capabiltiesProperties = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCapabiltiesProperties(capabiltiesProperties);
-	}
-
-	
-	@Test
-	public void testGetInterfaceArtifacts() throws Exception {
-		NodeType testSubject;
-		Map<String, InterfaceDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getInterfaceArtifacts();
-	}
-
-	
-	@Test
-	public void testSetInterfaceArtifacts() throws Exception {
-		NodeType testSubject;
-		Map<String, InterfaceDataDefinition> interfaceArtifacts = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setInterfaceArtifacts(interfaceArtifacts);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplateTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplateTest.java
deleted file mode 100644
index 0f1b918..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplateTest.java
+++ /dev/null
@@ -1,414 +0,0 @@
-package org.openecomp.sdc.be.model.jsontitan.datamodel;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
-import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListCapabiltyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
-import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
-
-
-public class TopologyTemplateTest {
-
-	private TopologyTemplate createTestSubject() {
-		return new TopologyTemplate();
-	}
-
-	
-	@Test
-	public void testGetInputs() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, PropertyDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getInputs();
-	}
-
-	
-	@Test
-	public void testSetInputs() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, PropertyDataDefinition> inputs = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setInputs(inputs);
-	}
-
-	
-	@Test
-	public void testGetInstInputs() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapPropertiesDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getInstInputs();
-	}
-
-	
-	@Test
-	public void testSetInstInputs() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapPropertiesDataDefinition> instInputs = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setInstInputs(instInputs);
-	}
-
-	
-	@Test
-	public void testGetHeatParameters() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, ? extends ToscaDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getHeatParameters();
-	}
-
-	
-	@Test
-	public void testSetHeatParameters() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, ? extends ToscaDataDefinition> heatParameters = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setHeatParameters(heatParameters);
-	}
-
-	
-	@Test
-	public void testGetInstAttributes() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapPropertiesDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getInstAttributes();
-	}
-
-	
-	@Test
-	public void testSetInstAttributes() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapPropertiesDataDefinition> instAttributes = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setInstAttributes(instAttributes);
-	}
-
-	
-	@Test
-	public void testGetInstProperties() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapPropertiesDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getInstProperties();
-	}
-
-	
-	@Test
-	public void testSetInstProperties() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapPropertiesDataDefinition> instProperties = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setInstProperties(instProperties);
-	}
-
-	
-	@Test
-	public void testGetGroups() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, GroupDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getGroups();
-	}
-
-	
-	@Test
-	public void testSetGroups() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, GroupDataDefinition> groups = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setGroups(groups);
-	}
-
-	
-	@Test
-	public void testGetInstGroups() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapGroupsDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getInstGroups();
-	}
-
-	
-	@Test
-	public void testSetInstGroups() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapGroupsDataDefinition> instGroups = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setInstGroups(instGroups);
-	}
-
-	
-	@Test
-	public void testGetServiceApiArtifacts() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, ArtifactDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getServiceApiArtifacts();
-	}
-
-	
-	@Test
-	public void testSetServiceApiArtifacts() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, ArtifactDataDefinition> serviceApiArtifacts = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setServiceApiArtifacts(serviceApiArtifacts);
-	}
-
-	
-	@Test
-	public void testGetCompositions() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, CompositionDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCompositions();
-	}
-
-	
-	@Test
-	public void testSetCompositions() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, CompositionDataDefinition> compositions = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCompositions(compositions);
-	}
-
-	
-	@Test
-	public void testGetCalculatedCapabilities() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapListCapabiltyDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCalculatedCapabilities();
-	}
-
-	
-	@Test
-	public void testSetCalculatedCapabilities() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapListCapabiltyDataDefinition> calculatedCapabilities = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCalculatedCapabilities(calculatedCapabilities);
-	}
-
-	
-	@Test
-	public void testGetCalculatedRequirements() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapListRequirementDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCalculatedRequirements();
-	}
-
-	
-	@Test
-	public void testSetCalculatedRequirements() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapListRequirementDataDefinition> calculatedRequirements = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCalculatedRequirements(calculatedRequirements);
-	}
-
-	
-	@Test
-	public void testGetFullfilledCapabilities() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapListCapabiltyDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getFullfilledCapabilities();
-	}
-
-	
-	@Test
-	public void testSetFullfilledCapabilities() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilities = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setFullfilledCapabilities(fullfilledCapabilities);
-	}
-
-	
-	@Test
-	public void testGetFullfilledRequirements() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapListRequirementDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getFullfilledRequirements();
-	}
-
-	
-	@Test
-	public void testSetFullfilledRequirements() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapListRequirementDataDefinition> fullfilledRequirements = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setFullfilledRequirements(fullfilledRequirements);
-	}
-
-	
-	@Test
-	public void testGetInstDeploymentArtifacts() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapArtifactDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getInstDeploymentArtifacts();
-	}
-
-	
-	@Test
-	public void testSetInstDeploymentArtifacts() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapArtifactDataDefinition> instDeploymentArtifacts = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setInstDeploymentArtifacts(instDeploymentArtifacts);
-	}
-
-	
-	@Test
-	public void testGetCalculatedCapabilitiesProperties() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapCapabiltyProperty> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCalculatedCapabilitiesProperties();
-	}
-
-	
-	@Test
-	public void testSetCalculatedCapabilitiesProperties() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapCapabiltyProperty> calculatedCapabilitiesProperties = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCalculatedCapabilitiesProperties(calculatedCapabilitiesProperties);
-	}
-
-	
-	@Test
-	public void testGetInstanceArtifacts() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapArtifactDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getInstanceArtifacts();
-	}
-
-	
-	@Test
-	public void testSetInstanceArtifacts() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, MapArtifactDataDefinition> instanceArtifacts = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setInstanceArtifacts(instanceArtifacts);
-	}
-
-	
-
-
-	
-	@Test
-	public void testGetComponentInstances() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, ComponentInstanceDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getComponentInstances();
-	}
-
-	
-	@Test
-	public void testSetComponentInstances() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, ComponentInstanceDataDefinition> instances = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setComponentInstances(instances);
-	}
-
-	
-	@Test
-	public void testGetRelations() throws Exception {
-		TopologyTemplate testSubject;
-		Map<String, RelationshipInstDataDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getRelations();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElementTypeEnumTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElementTypeEnumTest.java
deleted file mode 100644
index a112c9e..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElementTypeEnumTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.openecomp.sdc.be.model.jsontitan.datamodel;
-
-import org.junit.Test;
-
-
-public class ToscaElementTypeEnumTest {
-
-	private ToscaElementTypeEnum createTestSubject() {
-		return  ToscaElementTypeEnum.TopologyTemplate;
-	}
-
-	
-
-
-	
-	@Test
-	public void testGetValue() throws Exception {
-		ToscaElementTypeEnum testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getValue();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/enums/JsonConstantKeysEnumTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/enums/JsonConstantKeysEnumTest.java
deleted file mode 100644
index b00b13e..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/enums/JsonConstantKeysEnumTest.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.openecomp.sdc.be.model.jsontitan.enums;
-
-import org.junit.Test;
-
-
-public class JsonConstantKeysEnumTest {
-
-	private JsonConstantKeysEnum createTestSubject() {
-		return  JsonConstantKeysEnum.COMPOSITION;
-	}
-
-	
-	@Test
-	public void testGetValue() throws Exception {
-		JsonConstantKeysEnum testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getValue();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ArchiveOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ArchiveOperationTest.java
new file mode 100644
index 0000000..1b9da4d
--- /dev/null
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ArchiveOperationTest.java
@@ -0,0 +1,486 @@
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import fj.data.Either;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
+import org.openecomp.sdc.be.model.LifecycleStateEnum;
+import org.openecomp.sdc.be.model.ModelTestBase;
+import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
+import org.openecomp.sdc.be.model.jsontitan.utils.GraphTestUtils;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Created by yavivi on 21/03/2018.
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("classpath:application-context-test.xml")
+public class ArchiveOperationTest extends ModelTestBase {
+
+    private static final String CI_UID_RES1_CP = "cp_uid";
+    private static final String CI_UID_RES2_VL = "vl_uid";
+    private static final String CI_UID_SVC_PROXY = "svc_proxy_uid";
+
+    @Resource
+    private ArchiveOperation archiveOperation;
+
+    @Resource
+    private TitanDao titanDao;
+
+    private boolean isInitialized;
+
+    private GraphVertex serviceVertex1;
+    private GraphVertex archivedVertex1;
+
+    GraphVertex archiveVertex;
+    GraphVertex catalogVertex;
+
+    private GraphVertex serviceVertex1_0;
+    private GraphVertex serviceVertex1_1;
+    private GraphVertex serviceVertex2_0;
+    private GraphVertex serviceVertex3_0;
+    private GraphVertex serviceVertex3_1;
+
+    private GraphVertex serviceVertex0_1;
+    private GraphVertex serviceVertex0_2;
+    private GraphVertex serviceVertex0_3;
+    private GraphVertex serviceVertex0_4;
+    private GraphVertex serviceVertex0_5;
+
+    //Composition Elements
+    private GraphVertex compositionService;
+    private GraphVertex compositionResource1;
+    private GraphVertex compositionResource2;
+    private GraphVertex compositionServiceProxy;
+    private GraphVertex compositionAnotherService;
+
+    //For VSP Archive Notification
+    private GraphVertex vfResource0_1;
+    private GraphVertex vfResource0_2;
+    private GraphVertex vfResource1_0;
+    private String csarUuid = "123456789";;
+
+    @BeforeClass
+    public static void initTest(){
+        ModelTestBase.init();
+    }
+
+    @Before
+    public void beforeTest() {
+        if (!isInitialized) {
+            GraphTestUtils.clearGraph(titanDao);
+            initGraphForTest();
+            isInitialized = true;
+        }
+    }
+
+    @Test
+    public void testArchiveComponentSingleVersion(){
+        String componentId = serviceVertex1.getUniqueId();
+        Either<List<String>, ActionStatus> actionStatus = this.archiveOperation.archiveComponent(componentId);
+        assertThat(actionStatus.isLeft()).isTrue();
+        assertArchived(serviceVertex1.getUniqueId());
+    }
+
+    @Test
+    public void testArchiveComponentFailsWhenInCheckoutSingleVersion(){
+        checkoutComponent(serviceVertex1);
+        String componentId = serviceVertex1.getUniqueId();
+        Either<List<String>, ActionStatus> actionStatus = this.archiveOperation.archiveComponent(componentId);
+        assertThat(actionStatus.isLeft()).isFalse();
+        assertThat(actionStatus.right().value()).isEqualTo(ActionStatus.INVALID_SERVICE_STATE);
+    }
+
+    @Test
+    public void testArchiveWithWrongId() {
+        Either<List<String>, ActionStatus> actionStatus = this.archiveOperation.archiveComponent("fakeComponentId");
+        assertThat(actionStatus.isLeft()).isFalse();
+        assertThat(actionStatus.right().value()).isEqualTo(ActionStatus.RESOURCE_NOT_FOUND);
+    }
+
+    @Test
+    public void testAlreadyArchived() {
+        Either<List<String>, ActionStatus> actionStatus = this.archiveOperation.archiveComponent(archivedVertex1.getUniqueId());
+        assertThat(actionStatus.isLeft()).isTrue();
+        assertThat(actionStatus.left().value()).containsExactly(archivedVertex1.getUniqueId());
+    }
+
+    @Test
+    public void testScenario2_archive_1_0(){
+        Either<List<String>, ActionStatus> actionStatus = this.archiveOperation.archiveComponent(serviceVertex1_0.getUniqueId());
+        assertThat(actionStatus.isLeft()).isTrue();
+        assertThat(actionStatus.left().value()).containsExactlyInAnyOrder(serviceVertex1_0.getUniqueId(), serviceVertex1_1.getUniqueId());
+        assertArchived(serviceVertex1_0.getUniqueId());
+        assertArchived(serviceVertex1_1.getUniqueId());
+    }
+
+    @Test
+    public void testScenario2_archive_1_1(){
+        Either<List<String>, ActionStatus> actionStatus = this.archiveOperation.archiveComponent(serviceVertex1_1.getUniqueId());
+        assertThat(actionStatus.left().value()).containsExactlyInAnyOrder(serviceVertex1_0.getUniqueId(), serviceVertex1_1.getUniqueId());
+        assertArchived(serviceVertex1_0.getUniqueId());
+        assertArchived(serviceVertex1_1.getUniqueId());
+    }
+
+    @Test
+    public void testScenario4_oneLowOneHighestVersion(){
+        Either<List<String>, ActionStatus> actionStatus = this.archiveOperation.archiveComponent(serviceVertex0_2.getUniqueId());
+        assertThat(actionStatus.left().value()).containsExactlyInAnyOrder(serviceVertex0_2.getUniqueId(), serviceVertex0_1.getUniqueId(), serviceVertex0_3.getUniqueId(), serviceVertex0_4.getUniqueId(), serviceVertex0_5.getUniqueId());
+        assertArchived(serviceVertex0_1.getUniqueId());
+        assertArchived(serviceVertex0_2.getUniqueId());
+        assertArchived(serviceVertex0_3.getUniqueId());
+        assertArchived(serviceVertex0_4.getUniqueId());
+        assertArchived(serviceVertex0_5.getUniqueId());
+
+        actionStatus = this.archiveOperation.restoreComponent(serviceVertex0_2.getUniqueId());
+        assertThat(actionStatus.isLeft()).isTrue();
+        assertThat(actionStatus.left().value()).containsExactlyInAnyOrder(serviceVertex0_2.getUniqueId(), serviceVertex0_1.getUniqueId(), serviceVertex0_3.getUniqueId(), serviceVertex0_4.getUniqueId(), serviceVertex0_5.getUniqueId());
+    }
+
+
+    /////////////// Continue Here //////////////////
+    @Test
+    public void testScenario4_archiveFromNonHighest(){
+        Either<List<String>, ActionStatus> actionStatus = this.archiveOperation.archiveComponent(serviceVertex0_2.getUniqueId());
+        assertArchived(serviceVertex0_1.getUniqueId());
+        assertArchived(serviceVertex0_2.getUniqueId());
+        assertArchived(serviceVertex0_3.getUniqueId());
+        assertArchived(serviceVertex0_4.getUniqueId());
+        assertArchived(serviceVertex0_5.getUniqueId());
+
+        actionStatus = this.archiveOperation.restoreComponent(serviceVertex0_3.getUniqueId());
+        assertRestored(serviceVertex0_1.getUniqueId());
+        assertRestored(serviceVertex0_2.getUniqueId());
+        assertRestored(serviceVertex0_3.getUniqueId());
+        assertRestored(serviceVertex0_4.getUniqueId());
+        assertRestored(serviceVertex0_5.getUniqueId());
+    }
+
+    @Test
+    public void testArchiveFailsWhenHighestVersionIsInCheckoutState(){
+        checkoutComponent(serviceVertex0_5);
+        Either<List<String>, ActionStatus> actionStatus = this.archiveOperation.archiveComponent(serviceVertex0_2.getUniqueId());
+        assertThat(actionStatus.right().value()).isEqualTo(ActionStatus.INVALID_SERVICE_STATE);
+    }
+
+    @Test
+    public void testScenario3_archive_3_0(){
+        Either<List<String>, ActionStatus> actionStatus = this.archiveOperation.archiveComponent(serviceVertex3_0.getUniqueId());
+        assertArchived(serviceVertex3_0.getUniqueId());
+        assertArchived(serviceVertex3_1.getUniqueId());
+        assertArchivedProps(serviceVertex2_0.getUniqueId());
+    }
+
+    @Test
+    public void testArchivedOriginsCalculation(){
+
+        //Archive the CP resource
+        this.archiveOperation.archiveComponent(this.compositionResource1.getUniqueId());
+        this.archiveOperation.archiveComponent(this.compositionServiceProxy.getUniqueId());
+
+        List<String> ciWithArchivedOrigins = this.archiveOperation.setArchivedOriginsFlagInComponentInstances(this.compositionService);
+
+        //Validate that method returns the CI of CP
+        assertThat(ciWithArchivedOrigins).containsExactlyInAnyOrder(CI_UID_RES1_CP, CI_UID_SVC_PROXY);
+
+        Map<String, CompositionDataDefinition> compositionsJson = (Map<String, CompositionDataDefinition>) this.compositionService.getJson();
+
+        assertThat(compositionsJson).isNotNull();
+        assertThat(compositionsJson.get(JsonConstantKeysEnum.COMPOSITION.getValue())).isNotNull();
+
+        CompositionDataDefinition composition = compositionsJson.get(JsonConstantKeysEnum.COMPOSITION.getValue());
+
+        //Get all component instances from composition
+        Map<String, ComponentInstanceDataDefinition> componentInstances = composition.getComponentInstances();
+        for (ComponentInstanceDataDefinition ci : componentInstances.values()) {
+            //Verify that exactly 2 CIs are marked as archived
+            if (ci.getUniqueId().equals(CI_UID_RES1_CP) || ci.getUniqueId().equals(CI_UID_SVC_PROXY)) {
+                assertThat(ci.isOriginArchived()).isTrue();
+            }
+        }
+
+    }
+
+    @Test
+    public void testNoArchivedOriginsCalculation(){
+        List<String> ciWithArchivedOrigins = this.archiveOperation.setArchivedOriginsFlagInComponentInstances(this.compositionService);
+
+        //Validate that method returns the CI of CP
+        assertThat(ciWithArchivedOrigins).isEmpty();
+    }
+
+    @Test
+    public void testOnVspArchivedAndRestored(){
+        this.archiveOperation.onVspArchived(csarUuid);
+        //assertOnCommit();
+
+        assertOnVspArchived(true);
+
+        this.archiveOperation.onVspRestored(csarUuid);
+        //assertOnCommit();
+        assertOnVspArchived(false);
+
+        //Not Found CSAR UUID
+        ActionStatus result = this.archiveOperation.onVspRestored("fakeUuid");
+        //assertOnCommit();
+        assertThat(result).isEqualTo(ActionStatus.RESOURCE_NOT_FOUND);
+    }
+
+    private void assertOnVspArchived(boolean expectedValue) {
+        GraphVertex v = titanDao.getVertexById(vfResource0_1.getUniqueId()).left().value();
+        assertThat(v.getMetadataProperty(GraphPropertyEnum.IS_VSP_ARCHIVED)).isEqualTo(expectedValue);
+
+        v = titanDao.getVertexById(vfResource0_2.getUniqueId()).left().value();
+        assertThat(v.getMetadataProperty(GraphPropertyEnum.IS_VSP_ARCHIVED)).isEqualTo(expectedValue);
+
+        v = titanDao.getVertexById(vfResource1_0.getUniqueId()).left().value();
+        assertThat(v.getMetadataProperty(GraphPropertyEnum.IS_VSP_ARCHIVED)).isEqualTo(expectedValue);
+    }
+
+    /**************************
+     * Utility Methods
+     *************************/
+
+    private void checkoutComponent(GraphVertex serviceVertex0_5) {
+        Either<GraphVertex, TitanOperationStatus> vE = titanDao.getVertexById(serviceVertex0_5.getUniqueId());
+        GraphVertex v = vE.left().value();
+        v.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+        v.setJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+        titanDao.updateVertex(v);
+        assertOnCommit();
+    }
+
+    private void assertOnCommit(){
+        final TitanOperationStatus commit = this.titanDao.commit();
+        assertThat(commit).isEqualTo(TitanOperationStatus.OK);
+    }
+
+    private void assertArchived(String componentUniqueId) {
+        assertArchivedOrRestored(ArchiveOperation.Action.ARCHIVE, componentUniqueId);
+    }
+
+    private void assertRestored(String componentUniqueId) {
+        assertArchivedOrRestored(ArchiveOperation.Action.RESTORE, componentUniqueId);
+    }
+
+    private void assertArchivedOrRestored(ArchiveOperation.Action action,  String componentUniqueId) {
+        GraphVertex v = titanDao.getVertexById(componentUniqueId).left().value();
+
+        EdgeLabelEnum requiredEdge = action == ArchiveOperation.Action.ARCHIVE ? EdgeLabelEnum.ARCHIVE_ELEMENT : EdgeLabelEnum.CATALOG_ELEMENT;
+        EdgeLabelEnum otherEdge = action == ArchiveOperation.Action.ARCHIVE ? EdgeLabelEnum.CATALOG_ELEMENT : EdgeLabelEnum.ARCHIVE_ELEMENT;
+
+        GraphVertex parent = null;
+        Either<GraphVertex, TitanOperationStatus> otherLookup = null;
+        Boolean isHighest = (Boolean) v.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
+        if (isHighest != null && isHighest) {
+            //Highest version are linked to Archive/Catalog Root
+            parent = titanDao.getParentVertex(v, requiredEdge, JsonParseFlagEnum.NoParse).left().value();
+            otherLookup = titanDao.getParentVertex(v, otherEdge, JsonParseFlagEnum.NoParse);
+            assertThat(otherLookup.isRight()).isTrue();           //Verify that component is not linked to Catalog/Archive Root
+            assertThat(parent.getUniqueId()).isEqualTo(action == ArchiveOperation.Action.ARCHIVE ? this.archiveVertex.getUniqueId() : this.catalogVertex.getUniqueId()); //Verify that parent is indeed Archive Root
+        }
+
+        assertArchivedOrRestoredProps(action, v);
+    }
+
+    private void assertArchivedProps(String uniqueId) {
+        GraphVertex v =
+                titanDao.getVertexById(uniqueId).left().value();
+        assertArchivedOrRestoredProps(ArchiveOperation.Action.ARCHIVE, v);
+    }
+
+    private void assertRestoredProps(String uniqueId) {
+        GraphVertex v =
+                titanDao.getVertexById(uniqueId).left().value();
+        assertArchivedOrRestoredProps(ArchiveOperation.Action.RESTORE, v);
+    }
+
+    private void assertArchivedOrRestoredProps(ArchiveOperation.Action action, GraphVertex v) {
+        Object isArchived = v.getMetadataProperty(GraphPropertyEnum.IS_ARCHIVED);
+        Object archiveTime = v.getMetadataProperty(GraphPropertyEnum.ARCHIVE_TIME);
+        assertThat(isArchived).isNotNull().isEqualTo(action == ArchiveOperation.Action.ARCHIVE ? true : false);
+        assertThat(archiveTime).isNotNull();
+    }
+
+    /*******************************
+     * Preperation Methods
+     *******************************/
+    private void initGraphForTest() {
+        //Create Catalog Root
+        this.catalogVertex = GraphTestUtils.createRootCatalogVertex(titanDao);
+        //Create Archive Root
+        this.archiveVertex = GraphTestUtils.createRootArchiveVertex(titanDao);
+
+        createScenario1_SingleVersionNode();
+        createScenario2_TwoHighestVersions();
+        createScenario3_TwoHighestVersionsOneLowest();
+        createMiscServices();
+        createServiceCompositionForCalculatingArchivedOrigins();
+        createScenario4_1Highest4LowestVersions();
+        createResourcesForArchivedVsp();
+
+        assertOnCommit();
+    }
+
+    private void createScenario1_SingleVersionNode() {
+        //Create Service for Scenario 1 Tests (1 Service)
+        this.serviceVertex1 = GraphTestUtils.createServiceVertex(titanDao, propsForHighestVersion());
+
+        //Connect Service to Catalog Root
+        titanDao.createEdge(catalogVertex, serviceVertex1, EdgeLabelEnum.CATALOG_ELEMENT, null);
+    }
+
+    private void createScenario2_TwoHighestVersions() {
+        //Create Service for Scenario 2 Tests (1 Service)
+        this.serviceVertex1_0 = GraphTestUtils.createServiceVertex(titanDao, propsForHighestVersion());
+        this.serviceVertex1_1 = GraphTestUtils.createServiceVertex(titanDao, propsForHighestVersion());
+
+        titanDao.createEdge(serviceVertex1_0, serviceVertex1_1, EdgeLabelEnum.VERSION, null);
+
+        //Connect 1.0 and 1.1 to Catalog Root
+        titanDao.createEdge(catalogVertex, serviceVertex1_0, EdgeLabelEnum.CATALOG_ELEMENT, null);
+        titanDao.createEdge(catalogVertex, serviceVertex1_1, EdgeLabelEnum.CATALOG_ELEMENT, null);
+    }
+
+    private void createScenario3_TwoHighestVersionsOneLowest() {
+        //Create Service for Scenario 1 Tests (1 Service)
+        this.serviceVertex2_0 = GraphTestUtils.createServiceVertex(titanDao, propsForNonHighestVersion()); //NonHighestVersion
+        this.serviceVertex3_0 = GraphTestUtils.createServiceVertex(titanDao, propsForHighestVersion());
+        this.serviceVertex3_1 = GraphTestUtils.createServiceVertex(titanDao, propsForHighestVersion());
+
+        //Connect version edges
+        titanDao.createEdge(serviceVertex2_0, serviceVertex3_0, EdgeLabelEnum.VERSION, null);
+        titanDao.createEdge(serviceVertex3_0, serviceVertex3_1, EdgeLabelEnum.VERSION, null);
+
+        //Connect 3.0 and 3.1 to Catalog Root
+        titanDao.createEdge(catalogVertex, serviceVertex3_0, EdgeLabelEnum.CATALOG_ELEMENT, null);
+        titanDao.createEdge(catalogVertex, serviceVertex3_1, EdgeLabelEnum.CATALOG_ELEMENT, null);
+    }
+
+    private void createScenario4_1Highest4LowestVersions() {
+        //2 Lowest version only
+        this.serviceVertex0_1 = GraphTestUtils.createServiceVertex(titanDao, propsForNonHighestVersion());
+        this.serviceVertex0_2 = GraphTestUtils.createServiceVertex(titanDao, propsForNonHighestVersion());
+        this.serviceVertex0_3 = GraphTestUtils.createServiceVertex(titanDao, propsForNonHighestVersion());
+        this.serviceVertex0_4 = GraphTestUtils.createServiceVertex(titanDao, propsForNonHighestVersion());
+        this.serviceVertex0_5 = GraphTestUtils.createServiceVertex(titanDao, propsForHighestVersion());
+
+        titanDao.createEdge(serviceVertex0_1, serviceVertex0_2, EdgeLabelEnum.VERSION, null);
+        titanDao.createEdge(serviceVertex0_2, serviceVertex0_3, EdgeLabelEnum.VERSION, null);
+        titanDao.createEdge(serviceVertex0_3, serviceVertex0_4, EdgeLabelEnum.VERSION, null);
+        titanDao.createEdge(serviceVertex0_4, serviceVertex0_5, EdgeLabelEnum.VERSION, null);
+
+        titanDao.createEdge(catalogVertex, serviceVertex0_5, EdgeLabelEnum.CATALOG_ELEMENT, null);
+    }
+
+    private void createResourcesForArchivedVsp(){
+        Map<GraphPropertyEnum, Object> vfPropsNonHighest = propsForNonHighestVersion();
+        Map<GraphPropertyEnum, Object> vfPropsHighest = propsForNonHighestVersion();
+
+        vfPropsNonHighest.put(GraphPropertyEnum.CSAR_UUID, csarUuid);
+        vfPropsNonHighest.put(GraphPropertyEnum.IS_VSP_ARCHIVED, false);
+        vfPropsHighest.put(GraphPropertyEnum.CSAR_UUID, csarUuid);
+        vfPropsHighest.put(GraphPropertyEnum.IS_VSP_ARCHIVED, false);
+
+        this.vfResource0_1 = GraphTestUtils.createResourceVertex(titanDao, vfPropsNonHighest, ResourceTypeEnum.VF);
+        this.vfResource0_2 = GraphTestUtils.createResourceVertex(titanDao, vfPropsNonHighest, ResourceTypeEnum.VF);
+        this.vfResource1_0 = GraphTestUtils.createResourceVertex(titanDao, vfPropsHighest, ResourceTypeEnum.VF);
+
+        titanDao.createEdge(vfResource0_1, vfResource0_2, EdgeLabelEnum.VERSION, null);
+        titanDao.createEdge(vfResource0_2, vfResource1_0, EdgeLabelEnum.VERSION, null);
+    }
+
+    private void createMiscServices() {
+        //Create Service for Scenario 1 Tests (1 Service)
+        this.archivedVertex1 = GraphTestUtils.createServiceVertex(titanDao, new HashMap<>());
+
+        //Connect Service to Catalog Root
+        titanDao.createEdge(archiveVertex, archivedVertex1, EdgeLabelEnum.ARCHIVE_ELEMENT, null);
+    }
+
+    private void createServiceCompositionForCalculatingArchivedOrigins(){
+        //Service that point to another service in composition
+        this.compositionService = GraphTestUtils.createServiceVertex(titanDao, propsForHighestVersion());
+        this.compositionAnotherService = GraphTestUtils.createServiceVertex(titanDao, propsForHighestVersion());
+
+        this.compositionResource1 = GraphTestUtils.createResourceVertex(titanDao, propsForHighestVersion(), ResourceTypeEnum.CP);
+        this.compositionResource2 = GraphTestUtils.createResourceVertex(titanDao, propsForHighestVersion(), ResourceTypeEnum.VL);
+        this.compositionServiceProxy = GraphTestUtils.createResourceVertex(titanDao, propsForHighestVersion(), ResourceTypeEnum.ServiceProxy);
+
+        titanDao.createEdge(compositionService, compositionResource1, EdgeLabelEnum.INSTANCE_OF, null);
+        titanDao.createEdge(compositionService, compositionResource2, EdgeLabelEnum.INSTANCE_OF, null);
+        titanDao.createEdge(compositionService, compositionServiceProxy, EdgeLabelEnum.INSTANCE_OF, null);
+        titanDao.createEdge(compositionService, compositionAnotherService, EdgeLabelEnum.PROXY_OF, null);
+
+        createAndAttachCompositionJson(compositionService);
+    }
+
+    private void createAndAttachCompositionJson(GraphVertex compositionService) {
+        //Full composition json
+        Map<String, CompositionDataDefinition> compositions = new HashMap<>();
+        //Single composition data
+        CompositionDataDefinition composition = new CompositionDataDefinition();
+        //Instances Map
+        Map<String, ComponentInstanceDataDefinition> instances = new HashMap<>();
+
+        //Prepare Instances Map
+        ComponentInstanceDataDefinition instance = new ComponentInstanceDataDefinition();
+        instance.setUniqueId(CI_UID_RES1_CP);
+        instance.setComponentUid(compositionResource1.getUniqueId());
+        instances.put(CI_UID_RES1_CP, instance);
+
+        instance = new ComponentInstanceDataDefinition();
+        instance.setUniqueId(CI_UID_RES2_VL);
+        instance.setComponentUid(compositionResource2.getUniqueId());
+        instances.put(CI_UID_RES2_VL, instance);
+
+        instance = new ComponentInstanceDataDefinition();
+        instance.setUniqueId(CI_UID_SVC_PROXY);
+        instance.setComponentUid(compositionServiceProxy.getUniqueId());
+        instances.put(CI_UID_SVC_PROXY, instance);
+        
+        //Add Instances to Composition
+        composition.setComponentInstances(instances);
+        //Add to full composition
+        compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), composition);
+        //Add Full Json to vertex
+        compositionService.setJson(compositions);
+        //System.out.println(JsonParserUtils.toJson(compositions));
+        titanDao.updateVertex(compositionService);
+    }
+
+    private Map<GraphPropertyEnum, Object> propsForHighestVersion(){
+        Map<GraphPropertyEnum, Object> props = new HashMap();
+        props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
+        return props;
+    }
+
+    private Map<GraphPropertyEnum, Object> propsForNonHighestVersion(){
+        Map<GraphPropertyEnum, Object> props = new HashMap();
+        props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
+        props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
+        return props;
+    }
+
+}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperationsTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperationsTest.java
index a8fb609..410cef9 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperationsTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperationsTest.java
@@ -1,18 +1,6 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.CALLS_REAL_METHODS;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
+import fj.data.Either;
 import org.junit.Test;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
@@ -22,7 +10,12 @@
 import org.openecomp.sdc.be.model.ArtifactDefinition;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 
-import fj.data.Either;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
 
 public class ArtifactsOperationsTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ExternalReferencesOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ExternalReferencesOperationTest.java
index efa4020..e580fd5 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ExternalReferencesOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ExternalReferencesOperationTest.java
@@ -1,14 +1,6 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.when;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Resource;
-
+import fj.data.Either;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -24,10 +16,15 @@
 import org.openecomp.sdc.be.model.ModelTestBase;
 import org.openecomp.sdc.be.model.jsontitan.utils.GraphTestUtils;
 import org.openecomp.sdc.be.model.jsontitan.utils.IdMapper;
+import org.openecomp.sdc.be.model.operations.StorageException;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import fj.data.Either;
+import javax.annotation.Resource;
+import java.util.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
 
 /**
  * Created by yavivi on 26/01/2018.
@@ -36,6 +33,18 @@
 @ContextConfiguration("classpath:application-context-test.xml")
 public class ExternalReferencesOperationTest extends ModelTestBase {
 
+    private static final String COMPONENT_ID = "ci-MyComponentName";
+    private static final String COMPONENT2_ID = "ci-MyComponentName2";
+    private static final String MONITORING_OBJECT_TYPE = "monitoring";
+    private static final String WORKFLOW_OBJECT_TYPE = "workflow";
+    private static final String REF_1 = "ref1";
+    private static final String REF_2 = "ref2";
+    private static final String REF_3 = "ref3";
+    private static final String REF_4 = "ref4";
+    private static final String REF_5 = "ref5";
+    //workflow
+    private static final String REF_6 = "ref6";
+
     @Resource
     private ExternalReferencesOperation externalReferenceOperation;
 
@@ -45,20 +54,12 @@
     private boolean isInitialized;
 
     private GraphVertex serviceVertex;
+    private GraphVertex serviceVertex2;
+    private GraphVertex serviceVertex3;
 
     private String serviceVertexUuid;
-    private static final String COMPONENT_ID = "ci-MyComponentName";
-
-    private static final String MONITORING_OBJECT_TYPE = "monitoring";
-    private static final String WORKFLOW_OBJECT_TYPE = "workflow";
-    private static final String REF_1 = "ref1";
-    private static final String REF_2 = "ref2";
-    private static final String REF_3 = "ref3";
-    private static final String REF_4 = "ref4";
-    private static final String REF_5 = "ref5";
-
-    //workflow
-    private static final String REF_6 = "ref6";
+    private String serviceVertex2Uuid;
+    private String serviceVertex3Uuid;
 
     private IdMapper idMapper;
 
@@ -92,6 +93,44 @@
     }
 
     @Test
+    public void testAddExternalReferences_success() {
+        Map<String, List<String>> refsMap = Collections.singletonMap(MONITORING_OBJECT_TYPE, Arrays.asList(REF_1, REF_2));
+        externalReferenceOperation.addAllExternalReferences(serviceVertex3Uuid, COMPONENT_ID, refsMap);
+        Map<String, List<String>> allExternalReferences = externalReferenceOperation.getAllExternalReferences(serviceVertex3Uuid, COMPONENT_ID);
+        assertThat(allExternalReferences.size()).isEqualTo(1);
+        assertThat(allExternalReferences).flatExtracting(MONITORING_OBJECT_TYPE).containsExactly(REF_1, REF_2);
+        externalReferenceOperation.addAllExternalReferences(serviceVertex3Uuid, COMPONENT2_ID, refsMap);
+        Map<String, List<String>> allExternalReferences2 = externalReferenceOperation.getAllExternalReferences(serviceVertex3Uuid, COMPONENT2_ID);
+        assertThat(allExternalReferences2.size()).isEqualTo(1);
+        assertThat(allExternalReferences2).flatExtracting(MONITORING_OBJECT_TYPE).containsExactly(REF_1, REF_2);
+    }
+
+    @Test
+    public void testGetAllCIExternalRefs_success() {
+        Map<String, List<String>> allExternalReferences = externalReferenceOperation.getAllExternalReferences(serviceVertexUuid, COMPONENT_ID);
+        assertThat(allExternalReferences.size()).isEqualTo(2);
+        assertThat(allExternalReferences).flatExtracting(WORKFLOW_OBJECT_TYPE).containsExactly(REF_6);
+        assertThat(allExternalReferences).flatExtracting(MONITORING_OBJECT_TYPE).containsExactly(REF_1, REF_2, REF_3, REF_5);
+    }
+
+    @Test
+    public void testGetAllCIExternalRefs_noRefsExist() {
+        Map<String, List<String>> allExternalReferences = externalReferenceOperation.getAllExternalReferences(serviceVertex2Uuid, COMPONENT_ID);
+        assertThat(allExternalReferences.size()).isZero();
+    }
+
+    @Test
+    public void testGetAllCIExternalRefs_noSuchComponentInstance() {
+        Map<String, List<String>> allExternalReferences = externalReferenceOperation.getAllExternalReferences(serviceVertex2Uuid, "FAKE");
+        assertThat(allExternalReferences.size()).isZero();
+    }
+
+    @Test(expected=StorageException.class)
+    public void testGetAllCIExternalRefs_nonExitingService_throwsException() {
+        externalReferenceOperation.getAllExternalReferences("FAKE", COMPONENT_ID);
+    }
+
+    @Test
     public void testGetComponentInstanceExternalRef(){
         assertThat(externalReferenceOperation.getExternalReferences(this.serviceVertexUuid, COMPONENT_ID, MONITORING_OBJECT_TYPE).left().value()).contains(REF_1, REF_2, REF_3, REF_5);
         assertThat(externalReferenceOperation.getExternalReferences(this.serviceVertexUuid, COMPONENT_ID, WORKFLOW_OBJECT_TYPE).left().value()).containsExactly(REF_6);
@@ -155,13 +194,12 @@
 
         //Get List of references
         //final List<String> externalRefsByObjectType = mapComponentInstanceExternalRefs.externalRefsByObjectType(objectType);
-        final List<String> externalRefsByObjectType = mapComponentInstanceExternalRefs.getExternalRefsByObjectType(MONITORING_OBJECT_TYPE);
 
-        return externalRefsByObjectType;
+        return mapComponentInstanceExternalRefs.getExternalRefsByObjectType(MONITORING_OBJECT_TYPE);
     }
 
     private void initGraphForTest() {
-        //create a service and add 1 ref
+        //create a service
         this.serviceVertex = GraphTestUtils.createServiceVertex(titanDao, new HashMap<>());
         this.serviceVertexUuid = this.serviceVertex.getUniqueId();
 
@@ -174,6 +212,14 @@
         //workflow references
         externalReferenceOperation.addExternalReference(serviceVertexUuid, COMPONENT_ID, WORKFLOW_OBJECT_TYPE, REF_6);
 
+        //create a service without refs
+        serviceVertex2 = GraphTestUtils.createServiceVertex(titanDao, new HashMap<>());
+        serviceVertex2Uuid = serviceVertex2.getUniqueId();
+
+        //create a service for adding all references
+        serviceVertex3 = GraphTestUtils.createServiceVertex(titanDao, new HashMap<>());
+        serviceVertex3Uuid = serviceVertex3.getUniqueId();
+
         final TitanOperationStatus commit = this.titanDao.commit();
         assertThat(commit).isEqualTo(TitanOperationStatus.OK);
     }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/GroupsOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/GroupsOperationTest.java
new file mode 100644
index 0000000..191546d
--- /dev/null
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/GroupsOperationTest.java
@@ -0,0 +1,102 @@
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import fj.data.Either;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openecomp.sdc.be.dao.config.TitanSpringConfig;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.model.config.ModelOperationsSpringConfig;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = {TitanSpringConfig.class, ModelOperationsSpringConfig.class})
+public class GroupsOperationTest extends ModelTestBase {
+
+    @Autowired
+    private GroupsOperation groupsOperation;
+
+    @Autowired
+    TitanDao titanDao;
+
+    @Autowired
+    private ToscaOperationFacade toscaOperationFacade;
+    private Component container;
+
+    @BeforeClass
+    public static void initClass() {
+        ModelTestBase.init();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        container = new Resource();
+        container.setUniqueId(CONTAINER_ID);
+        Either<GraphVertex, TitanOperationStatus> createdCmpt = titanDao.createVertex(createBasicContainerGraphVertex());
+        assertThat(createdCmpt.isLeft()).isTrue();
+
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        titanDao.rollback();
+    }
+
+    @Test
+    public void addGroups_whenContainerHasNoGroups_associateContainerWithGroup() {
+        GroupDefinition g1 = createGroupDefinition("g1");
+        GroupDefinition g2 = createGroupDefinition("g2");
+        Either<List<GroupDefinition>, StorageOperationStatus> createGroups = groupsOperation.addGroups(container, asList(g1, g2));
+        assertThat(createGroups.isLeft()).isTrue();
+
+        ComponentParametersView getGroupsFilter = new ComponentParametersView(true);
+        getGroupsFilter.setIgnoreGroups(false);
+        Component cmptWithGroups = toscaOperationFacade.getToscaElement(CONTAINER_ID, getGroupsFilter).left().value();
+        assertThat(cmptWithGroups.getGroups())
+                .usingElementComparatorOnFields("name", "uniqueId")
+                .containsExactlyInAnyOrder(g1, g2);
+    }
+
+    @Test
+    public void addGroups_whenContainerHasGroups_addTheGivenGroupsToTheGroupsList() {
+        GroupDefinition g1 = createGroupDefinition("g1");
+        GroupDefinition g2 = createGroupDefinition("g2");
+        groupsOperation.addGroups(container, asList(g1, g2)).left().value();
+
+        GroupDefinition g3 = createGroupDefinition("g3");
+        GroupDefinition g4 = createGroupDefinition("g4");
+
+        groupsOperation.addGroups(container, asList(g3, g4)).left().value();
+
+        ComponentParametersView getGroupsFilter = new ComponentParametersView(true);
+        getGroupsFilter.setIgnoreGroups(false);
+        Component cmptWithGroups = toscaOperationFacade.getToscaElement(CONTAINER_ID, getGroupsFilter).left().value();
+        assertThat(cmptWithGroups.getGroups())
+                .usingElementComparatorOnFields("name", "uniqueId")
+                .containsExactlyInAnyOrder(g1, g2, g3, g4);
+
+    }
+
+    private GroupDefinition createGroupDefinition(String id) {
+        GroupDefinition groupDefinition = new GroupDefinition();
+        groupDefinition.setUniqueId(id);
+        groupDefinition.setName("name" + id);
+        return groupDefinition;
+    }
+
+
+}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfacesOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfacesOperationTest.java
index c3e8ce3..f2aefa0 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfacesOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfacesOperationTest.java
@@ -3,11 +3,7 @@
 import com.thinkaurelius.titan.core.TitanGraph;
 import com.thinkaurelius.titan.core.TitanVertex;
 import fj.data.Either;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.*;
 import org.junit.runner.RunWith;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
@@ -23,11 +19,7 @@
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
-import org.openecomp.sdc.be.model.InterfaceDefinition;
-import org.openecomp.sdc.be.model.LifecycleStateEnum;
-import org.openecomp.sdc.be.model.ModelTestBase;
-import org.openecomp.sdc.be.model.Operation;
-import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
@@ -42,11 +34,11 @@
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.*;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -365,7 +357,7 @@
         Map<String, MapDataDefinition> capProps = new HashMap();
         capProps.put("capName", dataToCreate);
 
-        Either<GraphVertex, StorageOperationStatus> res = nodeTypeOperation.assosiateElementToData(vfVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, capProps);
+        Either<GraphVertex, StorageOperationStatus> res = nodeTypeOperation.associateElementToData(vfVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, capProps);
 
         List<String> pathKeys = new ArrayList<>();
         pathKeys.add("capName");
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperationGraphTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperationGraphTest.java
new file mode 100644
index 0000000..ac8d8e7
--- /dev/null
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperationGraphTest.java
@@ -0,0 +1,239 @@
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.io.IoCore;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openecomp.sdc.be.dao.config.TitanSpringConfig;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
+import org.openecomp.sdc.be.model.ModelTestBase;
+import org.openecomp.sdc.be.model.config.ModelOperationsSpringConfig;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.annotation.Resource;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.*;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = {TitanSpringConfig.class, ModelOperationsSpringConfig.class})
+public class NodeTemplateOperationGraphTest extends ModelTestBase{
+    @Resource
+    private TitanDao titanDao;
+    @Resource
+    private NodeTemplateOperation nodeTemplateOperation;
+    
+    private TitanGraph graphT;
+    private GraphVertex containerVertex; 
+    private String containeId;
+  
+    @BeforeClass
+    public static void setupBeforeClass() {
+
+        ModelTestBase.init();
+    }
+    @Before
+    public void before(){
+       
+        Either<TitanGraph, TitanOperationStatus> graph = titanDao.getGraph();
+        graphT = graph.left().value();
+        
+        containerVertex = new GraphVertex(VertexTypeEnum.TOPOLOGY_TEMPLATE);
+        containeId = "containerId";
+        containerVertex.setUniqueId(containeId);
+        Either<GraphVertex, TitanOperationStatus> createVertex = titanDao.createVertex(containerVertex);
+        assertTrue(createVertex.isLeft());
+    }
+    
+    @After
+    public void after(){
+        titanDao.rollback();
+        
+    }
+    
+    
+    String outputDirectory = "C:\\Output";
+   
+    @Test
+    public void testCreateInstanceEdge(){
+ 
+        Map<String, List<String>> mapOriginToInstId = new HashMap<>();
+        createIntancesFromSameResource(mapOriginToInstId, 1, 3);
+        createIntancesFromSameResource(mapOriginToInstId, 2, 4);
+        createIntancesFromSameResource(mapOriginToInstId, 3, 1);
+          
+//        exportGraphMl(graphT);
+        
+        validateOnGraph(mapOriginToInstId, 3);
+    }
+    
+    @Test
+    public void testRemoveInstanceEdge(){
+        //create 3 instances from same resource orig1
+        Map<String, List<String>> mapOriginToInstId = new HashMap<>();
+        String originId = createIntancesFromSameResource(mapOriginToInstId, 1, 3);
+        validateOnGraph(mapOriginToInstId, 1);
+        
+        //remove instance 2
+        String instanceId = removeInstanceEdge(containerVertex, originId, 1, 1); 
+        mapOriginToInstId.get(originId).remove(instanceId);
+        validateOnGraph(mapOriginToInstId, 1);
+        
+        //create new instance from orig1
+        instanceId = createInstanceEdge(containerVertex, originId, 1, 4, false, null); 
+        mapOriginToInstId.get(originId).add(instanceId);
+        validateOnGraph(mapOriginToInstId, 1);
+        
+        //create 1 instance from same resource orig2
+        originId = createIntancesFromSameResource(mapOriginToInstId, 2, 1);
+        validateOnGraph(mapOriginToInstId, 2);
+        
+        //remove instance of orig 2  
+        instanceId = removeInstanceEdge(containerVertex, originId, 2, 1); 
+        mapOriginToInstId.get(originId).remove(instanceId);
+        validateOnGraph(mapOriginToInstId, 1);
+        
+    }
+    
+    @Test
+    public void testProxyInstanceEdge(){
+        Map<String, List<String>> mapOriginToInstId = new HashMap<>();
+        String proxyId  = createOrigin(2);
+        createIntancesFromSameResource(mapOriginToInstId, 1, 1, true, proxyId);
+        
+        validateOnGraph(mapOriginToInstId, 1);        
+    }
+    private void validateOnGraph(Map<String, List<String>> mapOriginToInstId, int expectedEdgeCount) {
+        validateOnGraph(mapOriginToInstId, expectedEdgeCount, false);
+    }
+    private void validateOnGraph(Map<String, List<String>> mapOriginToInstId, int expectedEdgeCount, boolean validateProxy) {
+        Iterable vertices = graphT.query().has(GraphPropertyEnum.UNIQUE_ID.getProperty(), containeId).vertices();
+        assertNotNull(vertices);
+        Iterator<TitanVertex> iterator = vertices.iterator();
+        assertTrue(iterator.hasNext());
+        Vertex containerV = iterator.next();
+        validatePerEdgeType(mapOriginToInstId, expectedEdgeCount, containerV, EdgeLabelEnum.INSTANCE_OF);
+        if ( validateProxy ){
+            validatePerEdgeType(mapOriginToInstId, expectedEdgeCount, containerV, EdgeLabelEnum.PROXY_OF);
+        }
+    }
+    private void validatePerEdgeType(Map<String, List<String>> mapOriginToInstId, int expectedEdgeCount, Vertex containerV, EdgeLabelEnum edgeLabel) {
+        Iterator<Edge> edges = containerV.edges(Direction.OUT, edgeLabel.name());
+        assertNotNull(edges);
+        
+        int counter = 0;
+        while (edges.hasNext()){
+            Edge edge = edges.next();
+            counter++;
+            validateEdge(edge, mapOriginToInstId);
+        }
+        assertEquals("check edge size", expectedEdgeCount, counter);
+    }
+    
+    
+    private String createIntancesFromSameResource(Map<String, List<String>> mapOriginToInstId, int originIndex, int countInstances) {
+        return createIntancesFromSameResource(mapOriginToInstId,  originIndex,  countInstances, false, null); 
+    }
+    
+    private String createIntancesFromSameResource(Map<String, List<String>> mapOriginToInstId, int originIndex, int countInstances, boolean isProxy, String proxyId) {
+        
+        List<String> exp = new ArrayList();
+        String originId = createOrigin(originIndex);
+        
+        for ( int i = 0; i < countInstances; i++){
+            String instanceId = createInstanceEdge(containerVertex, originId, originIndex, i+1, isProxy, proxyId); 
+            exp.add(instanceId);
+        }
+        mapOriginToInstId.put(originId, exp);
+        if ( isProxy ){
+            mapOriginToInstId.put(proxyId, exp); 
+        }
+        return originId;
+    }
+    
+    private String createInstanceEdge(GraphVertex containerVertex, String originId, int originIndex, int insIndex, boolean isProxy, String proxyId) {
+        ComponentInstanceDataDefinition componentInstance = new ComponentInstanceDataDefinition();
+        componentInstance.setComponentUid(originId);
+        String instanceId = buildInstanceId(originIndex, insIndex);
+        componentInstance.setUniqueId(instanceId);
+        componentInstance.setIsProxy(isProxy);
+        componentInstance.setSourceModelUid(proxyId);
+        StorageOperationStatus edgeStatus = nodeTemplateOperation.createInstanceEdge(containerVertex, componentInstance);
+        assertEquals("assertion createInstanceEdge", StorageOperationStatus.OK, edgeStatus);
+        return instanceId;
+    }
+    
+    private String buildInstanceId(int originIndex, int insIndex) {
+        StringBuffer sb = new StringBuffer("instanceId_");
+        sb.append(originIndex).append("-").append(insIndex);
+        return  sb.toString();
+    }
+    private String removeInstanceEdge(GraphVertex containerVertex, String originId, int originIndex, int insIndex) {
+        ComponentInstanceDataDefinition componentInstance = new ComponentInstanceDataDefinition();
+        componentInstance.setComponentUid(originId);
+        String instanceId = buildInstanceId(originIndex, insIndex);
+        componentInstance.setUniqueId(instanceId);
+        StorageOperationStatus edgeStatus = nodeTemplateOperation.removeInstanceEdge(containerVertex, componentInstance);
+        assertEquals("assertion removeInstanceEdge", StorageOperationStatus.OK, edgeStatus);
+        return instanceId;
+    }
+    
+    
+    private String createOrigin(int index) {
+        Either<GraphVertex, TitanOperationStatus> createVertex;
+        GraphVertex originVertex = new GraphVertex(VertexTypeEnum.NODE_TYPE);
+        String originId = "originId_" + index;
+        originVertex.setUniqueId(originId);
+        createVertex = titanDao.createVertex(originVertex);
+        assertTrue(createVertex.isLeft());
+        return originId;
+    }
+    private void validateEdge(Edge edge, Map<String, List<String>> mapOriginToInstId) {
+        List<String> expextedInList;
+        
+        Vertex originV = edge.inVertex();
+        String id = (String) titanDao.getProperty((TitanVertex)originV, GraphPropertyEnum.UNIQUE_ID.getProperty());
+        expextedInList = mapOriginToInstId.get(id);
+        
+        List<String> list = (List<String>) titanDao.getProperty(edge, EdgePropertyEnum.INSTANCES);
+        assertThat(list).hasSameSizeAs(expextedInList);
+        assertThat(list).containsOnlyElementsOf(expextedInList);
+    }
+    
+    private String exportGraphMl(TitanGraph graph) {
+        String result = null;
+        String outputFile = outputDirectory + File.separator + "exportGraph." + System.currentTimeMillis() + ".graphml";
+        try {
+            try (final OutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile))) {
+                graph.io(IoCore.graphml()).writer().normalize(true).create().writeGraph(os, graph);
+            }
+            result = outputFile;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+
+    }
+}
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperationTest.java
index 65baa42..fcde5b2 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperationTest.java
@@ -1,13 +1,7 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import com.google.common.collect.Lists;
+import fj.data.Either;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -17,198 +11,181 @@
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListCapabiltyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.ModelTestBase;
-import org.openecomp.sdc.be.model.RelationshipImpl;
-import org.openecomp.sdc.be.model.RelationshipInfo;
-import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
-import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.datatypes.elements.*;
+import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 
-import com.google.common.collect.Lists;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
-import fj.data.Either;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
 
 public class NodeTemplateOperationTest extends ModelTestBase {
 
-	private final static String COMPONENT_ID = "componentId";
-	private final static String TO_INSTANCE_ID = "toInstanceId";
-	private final static String FROM_INSTANCE_ID = "fromInstanceId";
-	private final static String RELATION_ID = "relationId";
-	private final static String CAPABILITY_OWNER_ID = "capabilityOwnerId";
-	private final static String CAPABILITY_UID = "capabilityUid";
-	private final static String CAPABILITY_NAME = "capabilityName";
-	private final static String REQUIREMENT_OWNER_ID = "requirementOwnerId";
-	private final static String REQUIREMENT_UID = "requirementUid";
-	private final static String REQUIREMENT_NAME = "requirementName";
-	private final static String RELATIONSHIP_TYPE = "relationshipType";
+    private final static String COMPONENT_ID = "componentId";
+    private final static String TO_INSTANCE_ID = "toInstanceId";
+    private final static String FROM_INSTANCE_ID = "fromInstanceId";
+    private final static String RELATION_ID = "relationId";
+    private final static String CAPABILITY_OWNER_ID = "capabilityOwnerId";
+    private final static String CAPABILITY_UID = "capabilityUid";
+    private final static String CAPABILITY_NAME = "capabilityName";
+    private final static String REQUIREMENT_OWNER_ID = "requirementOwnerId";
+    private final static String REQUIREMENT_UID = "requirementUid";
+    private final static String REQUIREMENT_NAME = "requirementName";
+    private final static String RELATIONSHIP_TYPE = "relationshipType";
 
-	private static Map<String, MapListCapabiltyDataDefinition> fulfilledCapability;
-	private static Map<String, MapListRequirementDataDefinition> fulfilledRequirement;
-	private static CapabilityDataDefinition capability;
-	private static RequirementDataDefinition requirement;
-	private static RequirementCapabilityRelDef relation;
+    private static Map<String, MapListCapabilityDataDefinition> fulfilledCapability;
+    private static Map<String, MapListRequirementDataDefinition> fulfilledRequirement;
+    private static CapabilityDataDefinition capability;
+    private static RequirementDataDefinition requirement;
+    private static RequirementCapabilityRelDef relation;
 
-	private static TitanDao titanDao;
-	private static NodeTemplateOperation operation;
+    private static TitanDao titanDao;
+    private static NodeTemplateOperation operation;
 
-	@BeforeClass
-	public static void setup() {
-		init();
-		titanDao = Mockito.mock(TitanDao.class);
-		operation = new NodeTemplateOperation();
-		operation.setTitanDao(titanDao);
-		buildDataDefinition();
-	}
+    @BeforeClass
+    public static void setup() {
+        init();
+        titanDao = Mockito.mock(TitanDao.class);
+        operation = new NodeTemplateOperation();
+        operation.setTitanDao(titanDao);
+        buildDataDefinition();
+    }
 
-	private static void buildDataDefinition() {
-		buildCapabiltyDataDefinition();
-		buildRequirementDataDefinition();
-		buildRelation();
-	}
+    private static void buildDataDefinition() {
+        buildCapabiltyDataDefinition();
+        buildRequirementDataDefinition();
+        buildRelation();
+    }
 
-	@Test
-	public void testGetFulfilledCapabilityByRelationSuccess() {
-		GraphVertex vertex = Mockito.mock(GraphVertex.class);
-		Either<GraphVertex, TitanOperationStatus> vertexRes = Either.left(vertex);
-		when(titanDao.getVertexById(eq(COMPONENT_ID), eq(JsonParseFlagEnum.ParseAll))).thenReturn(vertexRes);
+    @Test
+    public void testGetFulfilledCapabilityByRelationSuccess(){
+        GraphVertex vertex = Mockito.mock(GraphVertex.class);
+        Either<GraphVertex, TitanOperationStatus> vertexRes = Either.left(vertex);
+        when(titanDao.getVertexById(eq(COMPONENT_ID), eq(JsonParseFlagEnum.ParseAll))).thenReturn(vertexRes);
 
-		GraphVertex dataVertex = new GraphVertex();
-		dataVertex.setJson(fulfilledCapability);
-		Either<GraphVertex, TitanOperationStatus> childVertexRes = Either.left(dataVertex);
-		when(titanDao.getChildVertex(eq(vertex), eq(EdgeLabelEnum.FULLFILLED_CAPABILITIES),
-				eq(JsonParseFlagEnum.ParseJson))).thenReturn(childVertexRes);
-		Either<CapabilityDataDefinition, StorageOperationStatus> result = operation.getFulfilledCapabilityByRelation(
-				COMPONENT_ID, TO_INSTANCE_ID, relation, (rel, cap) -> isBelongingCapability(rel, cap));
-		assertTrue(result.isLeft());
-		assertTrue(result.left().value().equals(capability));
-	}
+        GraphVertex dataVertex = new GraphVertex();
+        dataVertex.setJson(fulfilledCapability);
+        Either<GraphVertex, TitanOperationStatus> childVertexRes = Either.left(dataVertex);
+        when(titanDao.getChildVertex(eq(vertex), eq(EdgeLabelEnum.FULLFILLED_CAPABILITIES), eq(JsonParseFlagEnum.ParseJson))).thenReturn(childVertexRes);
+        Either<CapabilityDataDefinition, StorageOperationStatus> result = operation.getFulfilledCapabilityByRelation(COMPONENT_ID, TO_INSTANCE_ID, relation, this::isBelongingCapability);
+        assertTrue(result.isLeft());
+        assertEquals(result.left().value(), capability);
+    }
 
-	@Test
-	public void testGetFulfilledRequirementByRelationSuccess() {
-		GraphVertex vertex = Mockito.mock(GraphVertex.class);
-		Either<GraphVertex, TitanOperationStatus> vertexRes = Either.left(vertex);
-		when(titanDao.getVertexById(eq(COMPONENT_ID), eq(JsonParseFlagEnum.ParseAll))).thenReturn(vertexRes);
+    @Test
+    public void testGetFulfilledRequirementByRelationSuccess(){
+        GraphVertex vertex = Mockito.mock(GraphVertex.class);
+        Either<GraphVertex, TitanOperationStatus> vertexRes = Either.left(vertex);
+        when(titanDao.getVertexById(eq(COMPONENT_ID), eq(JsonParseFlagEnum.ParseAll))).thenReturn(vertexRes);
 
-		GraphVertex dataVertex = new GraphVertex();
-		dataVertex.setJson(fulfilledRequirement);
-		Either<GraphVertex, TitanOperationStatus> childVertexRes = Either.left(dataVertex);
-		when(titanDao.getChildVertex(eq(vertex), eq(EdgeLabelEnum.FULLFILLED_REQUIREMENTS),
-				eq(JsonParseFlagEnum.ParseJson))).thenReturn(childVertexRes);
-		Either<RequirementDataDefinition, StorageOperationStatus> result = operation.getFulfilledRequirementByRelation(
-				COMPONENT_ID, FROM_INSTANCE_ID, relation, (rel, req) -> isBelongingRequirement(rel, req));
-		assertTrue(result.isLeft());
-		assertTrue(result.left().value().equals(requirement));
-	}
+        GraphVertex dataVertex = new GraphVertex();
+        dataVertex.setJson(fulfilledRequirement);
+        Either<GraphVertex, TitanOperationStatus> childVertexRes = Either.left(dataVertex);
+        when(titanDao.getChildVertex(eq(vertex), eq(EdgeLabelEnum.FULLFILLED_REQUIREMENTS), eq(JsonParseFlagEnum.ParseJson))).thenReturn(childVertexRes);
+        Either<RequirementDataDefinition, StorageOperationStatus> result = operation.getFulfilledRequirementByRelation(COMPONENT_ID, FROM_INSTANCE_ID, relation, this::isBelongingRequirement);
+        assertTrue(result.isLeft());
+        assertEquals(result.left().value(), requirement);
+    }
 
-	@Test
-	public void testGetFulfilledCapabilityByRelationNotFoundFailure() {
-		GraphVertex vertex = Mockito.mock(GraphVertex.class);
-		Either<GraphVertex, TitanOperationStatus> vertexRes = Either.left(vertex);
-		when(titanDao.getVertexById(eq(COMPONENT_ID), eq(JsonParseFlagEnum.ParseAll))).thenReturn(vertexRes);
+    @Test
+    public void testGetFulfilledCapabilityByRelationNotFoundFailure(){
+        GraphVertex vertex = Mockito.mock(GraphVertex.class);
+        Either<GraphVertex, TitanOperationStatus> vertexRes = Either.left(vertex);
+        when(titanDao.getVertexById(eq(COMPONENT_ID), eq(JsonParseFlagEnum.ParseAll))).thenReturn(vertexRes);
 
-		Either<GraphVertex, TitanOperationStatus> childVertexRes = Either.right(TitanOperationStatus.NOT_FOUND);
-		when(titanDao.getChildVertex(eq(vertex), eq(EdgeLabelEnum.FULLFILLED_CAPABILITIES),
-				eq(JsonParseFlagEnum.ParseJson))).thenReturn(childVertexRes);
-		Either<CapabilityDataDefinition, StorageOperationStatus> result = operation.getFulfilledCapabilityByRelation(
-				COMPONENT_ID, TO_INSTANCE_ID, relation, (rel, cap) -> isBelongingCapability(rel, cap));
-		assertTrue(result.isRight());
-		assertTrue(result.right().value() == StorageOperationStatus.NOT_FOUND);
-	}
+        Either<GraphVertex, TitanOperationStatus> childVertexRes = Either.right(TitanOperationStatus.NOT_FOUND);
+        when(titanDao.getChildVertex(eq(vertex), eq(EdgeLabelEnum.FULLFILLED_CAPABILITIES), eq(JsonParseFlagEnum.ParseJson))).thenReturn(childVertexRes);
+        Either<CapabilityDataDefinition, StorageOperationStatus> result = operation.getFulfilledCapabilityByRelation(COMPONENT_ID, TO_INSTANCE_ID, relation, this::isBelongingCapability);
+        assertTrue(result.isRight());
+        assertSame(result.right().value(), StorageOperationStatus.NOT_FOUND);
+    }
 
-	@Test
-	public void testGetFulfilledRequirementByRelationNotFoundFailure() {
-		GraphVertex vertex = Mockito.mock(GraphVertex.class);
-		Either<GraphVertex, TitanOperationStatus> vertexRes = Either.left(vertex);
-		when(titanDao.getVertexById(eq(COMPONENT_ID), eq(JsonParseFlagEnum.ParseAll))).thenReturn(vertexRes);
+    @Test
+    public void testGetFulfilledRequirementByRelationNotFoundFailure(){
+        GraphVertex vertex = Mockito.mock(GraphVertex.class);
+        Either<GraphVertex, TitanOperationStatus> vertexRes = Either.left(vertex);
+        when(titanDao.getVertexById(eq(COMPONENT_ID), eq(JsonParseFlagEnum.ParseAll))).thenReturn(vertexRes);
 
-		Either<GraphVertex, TitanOperationStatus> childVertexRes = Either.right(TitanOperationStatus.NOT_FOUND);
-		when(titanDao.getChildVertex(eq(vertex), eq(EdgeLabelEnum.FULLFILLED_REQUIREMENTS),
-				eq(JsonParseFlagEnum.ParseJson))).thenReturn(childVertexRes);
-		Either<RequirementDataDefinition, StorageOperationStatus> result = operation.getFulfilledRequirementByRelation(
-				COMPONENT_ID, FROM_INSTANCE_ID, relation, (rel, req) -> isBelongingRequirement(rel, req));
-		assertTrue(result.isRight());
-		assertTrue(result.right().value() == StorageOperationStatus.NOT_FOUND);
-	}
+        Either<GraphVertex, TitanOperationStatus> childVertexRes = Either.right(TitanOperationStatus.NOT_FOUND);
+        when(titanDao.getChildVertex(eq(vertex), eq(EdgeLabelEnum.FULLFILLED_REQUIREMENTS), eq(JsonParseFlagEnum.ParseJson))).thenReturn(childVertexRes);
+        Either<RequirementDataDefinition, StorageOperationStatus> result = operation.getFulfilledRequirementByRelation(COMPONENT_ID, FROM_INSTANCE_ID, relation, this::isBelongingRequirement);
+        assertTrue(result.isRight());
+        assertSame(result.right().value(), StorageOperationStatus.NOT_FOUND);
+    }
+ 
+    private static void buildRequirementDataDefinition() {
+        buildRequirement();
+        fulfilledRequirement = new HashMap<>();
+        MapListRequirementDataDefinition mapListRequirementDataDefinition = new MapListRequirementDataDefinition();
+        mapListRequirementDataDefinition.add(requirement.getCapability(), requirement);
+        fulfilledRequirement.put(FROM_INSTANCE_ID, mapListRequirementDataDefinition);
 
-	private static void buildRequirementDataDefinition() {
-		buildRequirement();
-		fulfilledRequirement = new HashMap<>();
-		MapListRequirementDataDefinition mapListRequirementDataDefinition = new MapListRequirementDataDefinition();
-		mapListRequirementDataDefinition.add(requirement.getCapability(), requirement);
-		fulfilledRequirement.put(FROM_INSTANCE_ID, mapListRequirementDataDefinition);
+    }
 
-	}
+    private static void buildRequirement() {
+        requirement = new RequirementDataDefinition();
+        requirement.setOwnerId(REQUIREMENT_OWNER_ID);
+        requirement.setUniqueId(REQUIREMENT_UID);
+        requirement.setName(REQUIREMENT_NAME);
+        requirement.setRelationship(RELATIONSHIP_TYPE);
+    }
 
-	private static void buildRequirement() {
-		requirement = new RequirementDataDefinition();
-		requirement.setOwnerId(REQUIREMENT_OWNER_ID);
-		requirement.setUniqueId(REQUIREMENT_UID);
-		requirement.setName(REQUIREMENT_NAME);
-		requirement.setRelationship(RELATIONSHIP_TYPE);
-	}
+    private static void buildCapabiltyDataDefinition() {
+        buildCapability();
+        fulfilledCapability = new HashMap<>();
+        MapListCapabilityDataDefinition mapListCapabiltyDataDefinition = new MapListCapabilityDataDefinition();
+        mapListCapabiltyDataDefinition.add(capability.getType(), capability);
+        fulfilledCapability.put(TO_INSTANCE_ID, mapListCapabiltyDataDefinition);
+    }
 
-	private static void buildCapabiltyDataDefinition() {
-		buildCapability();
-		fulfilledCapability = new HashMap<>();
-		MapListCapabiltyDataDefinition mapListCapabiltyDataDefinition = new MapListCapabiltyDataDefinition();
-		mapListCapabiltyDataDefinition.add(capability.getType(), capability);
-		fulfilledCapability.put(TO_INSTANCE_ID, mapListCapabiltyDataDefinition);
-	}
+    private static void buildCapability() {
+        capability = new CapabilityDataDefinition();
+        capability.setOwnerId(CAPABILITY_OWNER_ID);
+        capability.setUniqueId(CAPABILITY_UID);
+        capability.setName(CAPABILITY_NAME);
+    }
 
-	private static void buildCapability() {
-		capability = new CapabilityDataDefinition();
-		capability.setOwnerId(CAPABILITY_OWNER_ID);
-		capability.setUniqueId(CAPABILITY_UID);
-		capability.setName(CAPABILITY_NAME);
-	}
+    private static void buildRelation() {
 
-	private static void buildRelation() {
+        relation = new RequirementCapabilityRelDef();
+        CapabilityRequirementRelationship relationship = new CapabilityRequirementRelationship();
+        RelationshipInfo relationInfo = new RelationshipInfo();
+        relationInfo.setId(RELATION_ID);
+        relationship.setRelation(relationInfo);
 
-		relation = new RequirementCapabilityRelDef();
-		CapabilityRequirementRelationship relationship = new CapabilityRequirementRelationship();
-		RelationshipInfo relationInfo = new RelationshipInfo();
-		relationInfo.setId(RELATION_ID);
-		relationship.setRelation(relationInfo);
+        relation.setRelationships(Lists.newArrayList(relationship));
+        relation.setToNode(TO_INSTANCE_ID);
+        relation.setFromNode(FROM_INSTANCE_ID);
 
-		relation.setRelationships(Lists.newArrayList(relationship));
-		relation.setToNode(TO_INSTANCE_ID);
-		relation.setFromNode(FROM_INSTANCE_ID);
+        relationInfo.setCapabilityOwnerId(CAPABILITY_OWNER_ID);
+        relationInfo.setCapabilityUid(CAPABILITY_UID);
+        relationInfo.setCapability(CAPABILITY_NAME);
+        relationInfo.setRequirementOwnerId(REQUIREMENT_OWNER_ID);
+        relationInfo.setRequirementUid(REQUIREMENT_UID);
+        relationInfo.setRequirement(REQUIREMENT_NAME);
+        RelationshipImpl relationshipImpl  = new RelationshipImpl();
+        relationshipImpl.setType(RELATIONSHIP_TYPE);
+        relationInfo.setRelationships(relationshipImpl);
+    }
 
-		relationInfo.setCapabilityOwnerId(CAPABILITY_OWNER_ID);
-		relationInfo.setCapabilityUid(CAPABILITY_UID);
-		relationInfo.setCapability(CAPABILITY_NAME);
-		relationInfo.setRequirementOwnerId(REQUIREMENT_OWNER_ID);
-		relationInfo.setRequirementUid(REQUIREMENT_UID);
-		relationInfo.setRequirement(REQUIREMENT_NAME);
-		RelationshipImpl relationshipImpl = new RelationshipImpl();
-		relationshipImpl.setType(RELATIONSHIP_TYPE);
-		relationInfo.setRelationships(relationshipImpl);
-	}
+    private boolean isBelongingRequirement(RelationshipInfo relationshipInfo, RequirementDataDefinition req) {
+        return  req.getRelationship().equals(relationshipInfo.getRelationship().getType()) &&
+                req.getName().equals(relationshipInfo.getRequirement()) &&
+                req.getUniqueId().equals(relationshipInfo.getRequirementUid()) &&
+                req.getOwnerId().equals(relationshipInfo.getRequirementOwnerId());
+    }
 
-	private boolean isBelongingRequirement(RelationshipInfo relationshipInfo, RequirementDataDefinition req) {
-		return req.getRelationship().equals(relationshipInfo.getRelationship().getType())
-				&& req.getName().equals(relationshipInfo.getRequirement())
-				&& req.getUniqueId().equals(relationshipInfo.getRequirementUid())
-				&& req.getOwnerId().equals(relationshipInfo.getRequirementOwnerId());
-	}
-
-	private boolean isBelongingCapability(RelationshipInfo relationshipInfo, CapabilityDataDefinition cap) {
-		return cap.getName().equals(relationshipInfo.getCapability())
-				&& cap.getUniqueId().equals(relationshipInfo.getCapabilityUid())
-				&& cap.getOwnerId().equals(relationshipInfo.getCapabilityOwnerId());
+    private boolean isBelongingCapability(RelationshipInfo relationshipInfo, CapabilityDataDefinition cap) {
+        return     cap.getName().equals(relationshipInfo.getCapability()) &&
+                cap.getUniqueId().equals(relationshipInfo.getCapabilityUid()) &&
+                cap.getOwnerId().equals(relationshipInfo.getCapabilityOwnerId());
 	}
 
 	private NodeTemplateOperation createTestSubject() {
@@ -222,7 +199,7 @@
 
 		// default test
 		result = NodeTemplateOperation.getDefaultHeatTimeout();
-	}
+    }
 
 	
 
@@ -270,7 +247,7 @@
 		NodeTemplateOperation testSubject;
 		Map<String, ListCapabilityDataDefinition> capabilities = null;
 		ComponentInstanceDataDefinition componentInstance = null;
-		MapListCapabiltyDataDefinition result;
+		MapListCapabilityDataDefinition result;
 
 		// test 1
 		testSubject = createTestSubject();
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperationIntegrationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperationIntegrationTest.java
index 6a257d3..ee88e9a 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperationIntegrationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperationIntegrationTest.java
@@ -1,15 +1,6 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import static org.apache.commons.collections.ListUtils.union;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Resource;
-
+import fj.data.Either;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -35,7 +26,14 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import fj.data.Either;
+import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.commons.collections.ListUtils.union;
+import static org.assertj.core.api.Assertions.assertThat;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(classes = {TitanSpringConfig.class, ModelOperationsSpringConfig.class})
@@ -80,7 +78,7 @@
         titanDao.createVertex(resource);
         GraphVertex loadedResource = titanDao.getVertexById(CONTAINER_ID).left().value();
         topologyTemplateOperation.addToscaDataToToscaElement(loadedResource, EdgeLabelEnum.POLICIES, VertexTypeEnum.POLICIES, policy, JsonPresentationFields.UNIQUE_ID);
-        titanDao.commit();
+//        titanDao.commit();
     }
 
     @After
@@ -118,7 +116,7 @@
         componentParametersView.setIgnorePolicies(false);
         Either<ToscaElement, StorageOperationStatus> loadedCmptEither = topologyTemplateOperation.getToscaElement(CONTAINER_ID, componentParametersView);
 
-        assertThat(loadedCmptEither.isLeft());
+        assertThat(loadedCmptEither.isLeft()).isTrue();
         ToscaElement loadedCmpt = loadedCmptEither.left().value();
         assertThat(loadedCmpt).isInstanceOf(TopologyTemplate.class);
         @SuppressWarnings("unchecked") List<PropertyDataDefinition> allProperties = union(updatedProperties, nonUpdatedPropeties);
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperationTest.java
index 23b6b31..136f95b 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/PolicyOperationTest.java
@@ -1,13 +1,6 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.Collections;
-
+import fj.data.Either;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -26,7 +19,13 @@
 import org.openecomp.sdc.be.model.Resource;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 
-import fj.data.Either;
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
 public class PolicyOperationTest {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationCapabilityIntegrationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationCapabilityIntegrationTest.java
index 325b4c9..1f30d27 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationCapabilityIntegrationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationCapabilityIntegrationTest.java
@@ -1,14 +1,5 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Resource;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -19,7 +10,7 @@
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
-import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
+import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
 import org.openecomp.sdc.be.model.Component;
@@ -32,12 +23,20 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
+import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(classes = {TitanSpringConfig.class, ModelOperationsSpringConfig.class})
 public class TopologyTemplateOperationCapabilityIntegrationTest extends ModelTestBase {
 
     private static final String CONTAINER_ID = "id";
-    private Map<String, MapCapabiltyProperty> capabilitiesPropsMap;
+    private Map<String, MapCapabilityProperty> capabilitiesPropsMap;
     private List<CapabilityPropertyDataObject> capabilitiesProperties;
 
     @Resource
@@ -67,7 +66,7 @@
 
         //capablities props == Map<instance id, Map<capability id, Map<prop id, property>>>
         capabilitiesProperties.forEach(capabilitiesProperty -> {
-            capabilitiesPropsMap.computeIfAbsent(capabilitiesProperty.getInstanceId(), k -> new MapCapabiltyProperty(new HashMap<>()))
+            capabilitiesPropsMap.computeIfAbsent(capabilitiesProperty.getInstanceId(), k -> new MapCapabilityProperty(new HashMap<>()))
                              .getMapToscaDataDefinition().computeIfAbsent(capabilitiesProperty.getCapabilityId(), k -> new MapPropertiesDataDefinition(new HashMap<>()))
                              .getMapToscaDataDefinition().computeIfAbsent(capabilitiesProperty.getPropName(), k -> new PropertyDefinition(createPropWithValue(capabilitiesProperty.getPropValue())));
         });
@@ -76,19 +75,17 @@
         resource.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, CONTAINER_ID);
         titanDao.createVertex(resource);
         GraphVertex loadedResource = titanDao.getVertexById(CONTAINER_ID).left().value();
-        topologyTemplateOperation.assosiateElementToData(loadedResource, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, capabilitiesPropsMap).left().value();
-        titanDao.commit();
-
+        topologyTemplateOperation.associateElementToData(loadedResource, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, capabilitiesPropsMap).left().value();
     }
 
     @After
-    public void tearDown() throws Exception {
+    public void tearDown() {
         titanDao.rollback();
     }
 
     @Test
     public void overrideCalculatedCapabilityProperties() {
-        Map<String, MapCapabiltyProperty> loadedCapPropsMap = fetchCapabilitiesProps(CONTAINER_ID);
+        Map<String, MapCapabilityProperty> loadedCapPropsMap = fetchCapabilitiesProps(CONTAINER_ID);
         compareCapabilitiesProperties(capabilitiesProperties, loadedCapPropsMap);
         capabilityProperty1.setPropValue("newVal1");
         capabilityProperty3.setPropValue("newVal3");
@@ -96,7 +93,7 @@
         setPropertyValue(capabilitiesPropsMap, capabilityProperty3);
         StorageOperationStatus storageOperationStatus = topologyTemplateOperation.overrideToscaDataOfToscaElement(CONTAINER_ID, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, capabilitiesPropsMap);
         assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK);
-        Map<String, MapCapabiltyProperty> updatedCapPropsMap = fetchCapabilitiesProps(CONTAINER_ID);
+        Map<String, MapCapabilityProperty> updatedCapPropsMap = fetchCapabilitiesProps(CONTAINER_ID);
         compareCapabilitiesProperties(capabilitiesProperties, updatedCapPropsMap);
     }
 
@@ -106,7 +103,7 @@
         assertCapabilityPropValue(capabilityProperty2, "val2");
         assertCapabilityPropValue(capabilityProperty3, "val3");
 
-        MapCapabiltyProperty instance1Props = capabilitiesPropsMap.get("instance1");
+        MapCapabilityProperty instance1Props = capabilitiesPropsMap.get("instance1");
         capabilityProperty1.setPropValue("newVal1");
         setPropertyValue(capabilitiesPropsMap, capabilityProperty1);
 
@@ -123,36 +120,36 @@
         assertCapabilityPropValue(capabilityProperty3, "val3");//only instance1 props should be updated
     }
 
-    private Map<String, MapCapabiltyProperty> fetchCapabilitiesProps(String containerId) {
+    private Map<String, MapCapabilityProperty> fetchCapabilitiesProps(String containerId) {
         ComponentParametersView capabilityPropsFilter = new ComponentParametersView(true);
         capabilityPropsFilter.setIgnoreCapabiltyProperties(false);
         return ((TopologyTemplate) topologyTemplateOperation.getToscaElement(containerId, capabilityPropsFilter).left().value()).getCalculatedCapabilitiesProperties();
     }
 
-    private void compareCapabilitiesProperties(List<CapabilityPropertyDataObject> expected, Map<String, MapCapabiltyProperty> actual) {
+    private void compareCapabilitiesProperties(List<CapabilityPropertyDataObject> expected, Map<String, MapCapabilityProperty> actual) {
         expected.forEach(expectedCapabilityProp -> {
             assertThat(getPropertyValue(actual, expectedCapabilityProp.instanceId, expectedCapabilityProp.capabilityId, expectedCapabilityProp.propName))
                     .isEqualTo(expectedCapabilityProp.propValue);
         });
     }
 
-    private String getPropertyValue(Map<String, MapCapabiltyProperty> capabilityPropertyMap, String instance, String capability, String prop) {
+    private String getPropertyValue(Map<String, MapCapabilityProperty> capabilityPropertyMap, String instance, String capability, String prop) {
         return capabilityPropertyMap.get(instance).getMapToscaDataDefinition().get(capability).getMapToscaDataDefinition().get(prop).getValue();
     }
 
-    private void setPropertyValue(Map<String, MapCapabiltyProperty> capabilityPropertyMap, CapabilityPropertyDataObject capabilityProperty) {
+    private void setPropertyValue(Map<String, MapCapabilityProperty> capabilityPropertyMap, CapabilityPropertyDataObject capabilityProperty) {
         setPropertyValue(capabilityPropertyMap.get(capabilityProperty.getInstanceId()), capabilityProperty);
 
     }
 
-    private void setPropertyValue(MapCapabiltyProperty capabilitiesInstanceProperties, CapabilityPropertyDataObject capabilityProperty) {
+    private void setPropertyValue(MapCapabilityProperty capabilitiesInstanceProperties, CapabilityPropertyDataObject capabilityProperty) {
         capabilitiesInstanceProperties.getMapToscaDataDefinition().get(capabilityProperty.getCapabilityId())
                                       .getMapToscaDataDefinition().get(capabilityProperty.getPropName())
                                       .setValue(capabilityProperty.getPropValue());
     }
 
     private void assertCapabilityPropValue(CapabilityPropertyDataObject prop, String expectedValue) {
-        Map<String, MapCapabiltyProperty> loadedCapPropsMap = fetchCapabilitiesProps(CONTAINER_ID);
+        Map<String, MapCapabilityProperty> loadedCapPropsMap = fetchCapabilitiesProps(CONTAINER_ID);
         String propertyValue = getPropertyValue(loadedCapPropsMap, prop.getInstanceId(), prop.getCapabilityId(), prop.getPropName());
         assertThat(propertyValue).isEqualTo(expectedValue);
     }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationIntegrationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationIntegrationTest.java
deleted file mode 100644
index d7a6986..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationIntegrationTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-package org.openecomp.sdc.be.model.jsontitan.operations;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Resource;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.openecomp.sdc.be.dao.config.TitanSpringConfig;
-import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
-import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
-import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
-import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
-import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
-import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
-import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.ComponentParametersView;
-import org.openecomp.sdc.be.model.ModelTestBase;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.config.ModelOperationsSpringConfig;
-import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
-import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = {TitanSpringConfig.class, ModelOperationsSpringConfig.class})
-public class TopologyTemplateOperationIntegrationTest extends ModelTestBase {
-
-    private static final String CONTAINER_ID = "id";
-    private Map<String, MapCapabiltyProperty> capabilitiesPropsMap;
-    private List<CapabilityPropertyDataObject> capabilitiesProperties;
-
-    @Resource
-    private TopologyTemplateOperation topologyTemplateOperation;
-
-    @Resource
-    private TitanDao titanDao;
-    private CapabilityPropertyDataObject capabilityProperty1;
-    private CapabilityPropertyDataObject capabilityProperty2;
-    private CapabilityPropertyDataObject capabilityProperty3;
-
-    @BeforeClass
-    public static void setupBeforeClass() {
-
-        ModelTestBase.init();
-    }
-
-    @Before
-    public void setUp() throws Exception {
-
-        capabilitiesPropsMap = new HashMap<>();
-        capabilityProperty1 = new CapabilityPropertyDataObject("instance1", "capability1", "prop1", "val1");
-        capabilityProperty2 = new CapabilityPropertyDataObject("instance1", "capability2", "prop2", "val2");
-        capabilityProperty3 = new CapabilityPropertyDataObject("instance2", "capability3", "prop3", "val3");
-        capabilitiesProperties = Arrays.asList(capabilityProperty1, capabilityProperty2, capabilityProperty3);
-
-
-        //capablities props == Map<instance id, Map<capability id, Map<prop id, property>>>
-        capabilitiesProperties.forEach(capabilitiesProperty -> {
-            capabilitiesPropsMap.computeIfAbsent(capabilitiesProperty.getInstanceId(), k -> new MapCapabiltyProperty(new HashMap<>()))
-                             .getMapToscaDataDefinition().computeIfAbsent(capabilitiesProperty.getCapabilityId(), k -> new MapPropertiesDataDefinition(new HashMap<>()))
-                             .getMapToscaDataDefinition().computeIfAbsent(capabilitiesProperty.getPropName(), k -> new PropertyDefinition(createPropWithValue(capabilitiesProperty.getPropValue())));
-        });
-
-        GraphVertex resource = new GraphVertex(VertexTypeEnum.TOPOLOGY_TEMPLATE);
-        resource.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, CONTAINER_ID);
-        titanDao.createVertex(resource);
-        GraphVertex loadedResource = titanDao.getVertexById(CONTAINER_ID).left().value();
-        topologyTemplateOperation.assosiateElementToData(loadedResource, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, capabilitiesPropsMap).left().value();
-        titanDao.commit();
-
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        titanDao.rollback();
-    }
-
-    @Test
-    public void overrideCalculatedCapabilityProperties() {
-        Map<String, MapCapabiltyProperty> loadedCapPropsMap = fetchCapabilitiesProps(CONTAINER_ID);
-        compareCapabilitiesProperties(capabilitiesProperties, loadedCapPropsMap);
-        capabilityProperty1.setPropValue("newVal1");
-        capabilityProperty3.setPropValue("newVal3");
-        setPropertyValue(capabilitiesPropsMap, capabilityProperty1);
-        setPropertyValue(capabilitiesPropsMap, capabilityProperty3);
-        StorageOperationStatus storageOperationStatus = topologyTemplateOperation.overrideToscaDataOfToscaElement(CONTAINER_ID, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, capabilitiesPropsMap);
-        assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK);
-        Map<String, MapCapabiltyProperty> updatedCapPropsMap = fetchCapabilitiesProps(CONTAINER_ID);
-        compareCapabilitiesProperties(capabilitiesProperties, updatedCapPropsMap);
-    }
-
-    @Test
-    public void updateToscaDataDeepElementsBlockToToscaElement() {
-        assertCapabilityPropValue(capabilityProperty1, "val1");
-        assertCapabilityPropValue(capabilityProperty2, "val2");
-        assertCapabilityPropValue(capabilityProperty3, "val3");
-
-        MapCapabiltyProperty instance1Props = capabilitiesPropsMap.get("instance1");
-        capabilityProperty1.setPropValue("newVal1");
-        setPropertyValue(capabilitiesPropsMap, capabilityProperty1);
-
-        capabilityProperty3.setPropValue("newVal3");
-        setPropertyValue(capabilitiesPropsMap, capabilityProperty3);
-
-        Component component = new org.openecomp.sdc.be.model.Resource();
-        component.setUniqueId(CONTAINER_ID);
-        StorageOperationStatus updateStatus = topologyTemplateOperation.updateToscaDataDeepElementsBlockToToscaElement(CONTAINER_ID, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, instance1Props, "instance1");
-
-        assertThat(updateStatus).isEqualTo(StorageOperationStatus.OK);
-        assertCapabilityPropValue(capabilityProperty1, "newVal1");
-        assertCapabilityPropValue(capabilityProperty2, "val2");
-        assertCapabilityPropValue(capabilityProperty3, "val3");//only instance1 props should be updated
-    }
-
-    private Map<String, MapCapabiltyProperty> fetchCapabilitiesProps(String containerId) {
-        ComponentParametersView capabilityPropsFilter = new ComponentParametersView(true);
-        capabilityPropsFilter.setIgnoreCapabiltyProperties(false);
-        return ((TopologyTemplate) topologyTemplateOperation.getToscaElement(containerId, capabilityPropsFilter).left().value()).getCalculatedCapabilitiesProperties();
-    }
-
-    private void compareCapabilitiesProperties(List<CapabilityPropertyDataObject> expected, Map<String, MapCapabiltyProperty> actual) {
-        expected.forEach(expectedCapabilityProp -> {
-            assertThat(getPropertyValue(actual, expectedCapabilityProp.instanceId, expectedCapabilityProp.capabilityId, expectedCapabilityProp.propName))
-                    .isEqualTo(expectedCapabilityProp.propValue);
-        });
-    }
-
-    private String getPropertyValue(Map<String, MapCapabiltyProperty> capabilityPropertyMap, String instance, String capability, String prop) {
-        return capabilityPropertyMap.get(instance).getMapToscaDataDefinition().get(capability).getMapToscaDataDefinition().get(prop).getValue();
-    }
-
-    private void setPropertyValue(Map<String, MapCapabiltyProperty> capabilityPropertyMap, CapabilityPropertyDataObject capabilityProperty) {
-        setPropertyValue(capabilityPropertyMap.get(capabilityProperty.getInstanceId()), capabilityProperty);
-
-    }
-
-    private void setPropertyValue(MapCapabiltyProperty capabilitiesInstanceProperties, CapabilityPropertyDataObject capabilityProperty) {
-        capabilitiesInstanceProperties.getMapToscaDataDefinition().get(capabilityProperty.getCapabilityId())
-                                      .getMapToscaDataDefinition().get(capabilityProperty.getPropName())
-                                      .setValue(capabilityProperty.getPropValue());
-    }
-
-    private void assertCapabilityPropValue(CapabilityPropertyDataObject prop, String expectedValue) {
-        Map<String, MapCapabiltyProperty> loadedCapPropsMap = fetchCapabilitiesProps(CONTAINER_ID);
-        String propertyValue = getPropertyValue(loadedCapPropsMap, prop.getInstanceId(), prop.getCapabilityId(), prop.getPropName());
-        assertThat(propertyValue).isEqualTo(expectedValue);
-    }
-
-
-    private PropertyDefinition createPropWithValue(String val) {
-        PropertyDefinition propertyDefinition = new PropertyDefinition();
-        propertyDefinition.setValue(val);
-        return propertyDefinition;
-    }
-
-    private static class CapabilityPropertyDataObject {
-        private String instanceId;
-        private String capabilityId;
-        private String propName;
-        private String propValue;
-
-        CapabilityPropertyDataObject(String instanceId, String capabilityId, String propName, String propValue) {
-            this.instanceId = instanceId;
-            this.capabilityId = capabilityId;
-            this.propName = propName;
-            this.propValue = propValue;
-        }
-
-        String getInstanceId() {
-            return instanceId;
-        }
-
-        String getCapabilityId() {
-            return capabilityId;
-        }
-
-        String getPropName() {
-            return propName;
-        }
-
-        String getPropValue() {
-            return propValue;
-        }
-
-        void setPropValue(String propValue) {
-            this.propValue = propValue;
-        }
-    }
-}
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationTest.java
index e8655b5..6193c5d 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperationTest.java
@@ -1,13 +1,7 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-import java.util.Collections;
-import java.util.HashMap;
-
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
@@ -19,15 +13,19 @@
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
+import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.model.PolicyDefinition;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 
-import com.thinkaurelius.titan.core.TitanVertex;
+import java.util.Collections;
+import java.util.HashMap;
 
-import fj.data.Either;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
 //error scenarios
@@ -58,7 +56,7 @@
     @Test
     public void updateToscaDataDeepElements_failedToFetchContainerVertex() {
         when(titanDao.getVertexById(CONTAINER_ID, JsonParseFlagEnum.NoParse)).thenReturn(Either.right(TitanOperationStatus.INVALID_ID));
-        StorageOperationStatus storageOperationStatus = topologyTemplateOperation.updateToscaDataDeepElementsBlockToToscaElement(CONTAINER_ID, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, new MapCapabiltyProperty(), "");
+        StorageOperationStatus storageOperationStatus = topologyTemplateOperation.updateToscaDataDeepElementsBlockToToscaElement(CONTAINER_ID, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, new MapCapabilityProperty(), "");
         assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.INVALID_ID);
     }
 
@@ -67,44 +65,44 @@
         GraphVertex containerVertex = new GraphVertex();
         when(titanDao.getVertexById(CONTAINER_ID, JsonParseFlagEnum.NoParse)).thenReturn(Either.left(containerVertex));
         when(titanDao.getChildVertex(containerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, JsonParseFlagEnum.ParseJson)).thenReturn(Either.right(TitanOperationStatus.NOT_FOUND));
-        StorageOperationStatus storageOperationStatus = topologyTemplateOperation.updateToscaDataDeepElementsBlockToToscaElement(CONTAINER_ID, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, new MapCapabiltyProperty(), "");
+        StorageOperationStatus storageOperationStatus = topologyTemplateOperation.updateToscaDataDeepElementsBlockToToscaElement(CONTAINER_ID, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, new MapCapabilityProperty(), "");
         assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.NOT_FOUND);
     }
     
-	@Test
+    @Test
     public void addPolicyToToscaElementSuccessTest(){
-    	TitanOperationStatus status = TitanOperationStatus.OK;
-    	StorageOperationStatus result = addPolicyToToscaElementWithStatus(status);
-    	assertThat(result).isEqualTo(StorageOperationStatus.OK);
+        TitanOperationStatus status = TitanOperationStatus.OK;
+        StorageOperationStatus result = addPolicyToToscaElementWithStatus(status);
+        assertThat(result).isEqualTo(StorageOperationStatus.OK);
     }
     
-	@Test
+    @Test
     public void addPolicyToToscaElementFailureTest(){
-    	TitanOperationStatus status = TitanOperationStatus.ALREADY_EXIST;
-    	StorageOperationStatus result = addPolicyToToscaElementWithStatus(status);
-    	assertThat(result).isEqualTo(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
+        TitanOperationStatus status = TitanOperationStatus.ALREADY_EXIST;
+        StorageOperationStatus result = addPolicyToToscaElementWithStatus(status);
+        assertThat(result).isEqualTo(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
     }
 
-	@SuppressWarnings("unchecked")
-	private StorageOperationStatus addPolicyToToscaElementWithStatus(TitanOperationStatus status) {
-		GraphVertex componentV = new GraphVertex();
-    	componentV.setVertex(Mockito.mock(TitanVertex.class));
-    	GraphVertex dataV = new GraphVertex();
-    	dataV.setVertex(Mockito.mock(TitanVertex.class));
-    	String componentName = "componentName";
-    	String componentId = UniqueIdBuilder.buildResourceUniqueId();
-    	String policyTypeName = "org.openecomp.policies.placement.valet.Affinity";
-    	componentV.setJsonMetadataField(JsonPresentationFields.NAME, componentName);
-    	componentV.setUniqueId(componentId);
-    	PolicyDefinition policy = new PolicyDefinition();
-    	policy.setPolicyTypeName(policyTypeName);
-    	int counter = 0;
-    	Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = Either.right(TitanOperationStatus.NOT_FOUND);
-    	when(titanDao.getChildVertex(eq(componentV), eq(EdgeLabelEnum.POLICIES), eq(JsonParseFlagEnum.ParseJson))).thenReturn(toscaDataVertexRes);
-		Either<GraphVertex, TitanOperationStatus> createVertex = Either.left(dataV);
-		when(titanDao.createVertex(any(GraphVertex.class))).thenReturn(createVertex);
-		when(titanDao.createEdge(any(TitanVertex.class), any(TitanVertex.class), any(EdgeLabelEnum.class), any(HashMap.class))).thenReturn(status);
-    	return topologyTemplateOperation.addPolicyToToscaElement(componentV, policy, counter);
-	}
+    @SuppressWarnings("unchecked")
+    private StorageOperationStatus addPolicyToToscaElementWithStatus(TitanOperationStatus status) {
+        GraphVertex componentV = new GraphVertex();
+        componentV.setVertex(Mockito.mock(TitanVertex.class));
+        GraphVertex dataV = new GraphVertex();
+        dataV.setVertex(Mockito.mock(TitanVertex.class));
+        String componentName = "componentName";
+        String componentId = UniqueIdBuilder.buildResourceUniqueId();
+        String policyTypeName = "org.openecomp.policies.placement.valet.Affinity";
+        componentV.setJsonMetadataField(JsonPresentationFields.NAME, componentName);
+        componentV.setUniqueId(componentId);
+        PolicyDefinition policy = new PolicyDefinition();
+        policy.setPolicyTypeName(policyTypeName);
+        int counter = 0;
+        Either<GraphVertex, TitanOperationStatus> toscaDataVertexRes = Either.right(TitanOperationStatus.NOT_FOUND);
+        when(titanDao.getChildVertex(eq(componentV), eq(EdgeLabelEnum.POLICIES), eq(JsonParseFlagEnum.ParseJson))).thenReturn(toscaDataVertexRes);
+        Either<GraphVertex, TitanOperationStatus> createVertex = Either.left(dataV);
+        when(titanDao.createVertex(any(GraphVertex.class))).thenReturn(createVertex);
+        when(titanDao.createEdge(any(TitanVertex.class), any(TitanVertex.class), any(EdgeLabelEnum.class), any(HashMap.class))).thenReturn(status);
+        return topologyTemplateOperation.addPolicyToToscaElement(componentV, policy, counter);
+    }
     
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationCatalogTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationCatalogTest.java
new file mode 100644
index 0000000..bffefd8
--- /dev/null
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationCatalogTest.java
@@ -0,0 +1,73 @@
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import fj.data.Either;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
+import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.model.catalog.CatalogComponent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ToscaElementOperationCatalogTest {
+
+    private ArrayList<Vertex> vertexList = new ArrayList<>();
+
+    @Mock
+    Vertex vertex;
+    @Mock
+    TitanDao titanDao;
+    @Mock
+    VertexProperty<Object> property;
+
+    @InjectMocks
+    private ToscaElementOperation toscaOperation = new TopologyTemplateOperation();
+
+    @Before
+    public void setUp() {
+        vertexList.add(vertex);
+        when(titanDao.getCatalogOrArchiveVerticies(true)).thenReturn(Either.left(vertexList.iterator()));
+        when(titanDao.getChildVertex(vertex, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse))
+                .thenReturn(Either.right(TitanOperationStatus.NOT_FOUND));
+        when(vertex.property(GraphPropertiesDictionary.METADATA.getProperty())).thenReturn(property);
+    }
+
+    @Test
+    public void getComponentFromCatalogWhenDeleteIsTrue() {
+        final String vertexJsonIsDeletedTrue = "{\"lifecycleState\":\"CERTIFIED\",\"componentType\":\"RESOURCE\",\"vendorRelease\":\"1\",\"contactId\":\"ah7840\",\"lastUpdateDate\":1496119811038,\"icon\":\"att\",\"description\":\"Cloud\",\"creationDate\":1459432094781,\"vendorName\":\"AT&T\",\"mandatory\":false,\"version\":\"1.0\",\"tags\":[\"Cloud\"],\"highestVersion\":true,\"systemName\":\"Cloud\",\"name\":\"Cloud\",\"isDeleted\":true,\"invariantUuid\":\"ab5263fd-115c-41f2-8d0c-8b9279bce2b2\",\"UUID\":\"208cf7df-68a1-4ae7-afc9-409ea8012332\",\"normalizedName\":\"cloud\",\"toscaResourceName\":\"org.openecomp.resource.Endpoint.Cloud\",\"uniqueId\":\"9674e7e1-bc1a-41fe-b503-fbe996801475\",\"resourceType\":\"VFC\"}";
+        when(property.value()).thenReturn(vertexJsonIsDeletedTrue);
+        List<CatalogComponent> componentList = toscaOperation.getElementCatalogData(true, null).left().value();
+        assertTrue(componentList.isEmpty());
+    }
+
+    @Test
+    public void getComponentFromCatalogWhenDeleteNotFound() {
+        final String vertexJsonIsDeletedNotFound = "{\"lifecycleState\":\"CERTIFIED\",\"componentType\":\"RESOURCE\",\"vendorRelease\":\"1\",\"contactId\":\"ah7840\",\"lastUpdateDate\":1496119811038,\"icon\":\"att\",\"description\":\"Cloud\",\"creationDate\":1459432094781,\"vendorName\":\"AT&T\",\"mandatory\":false,\"version\":\"1.0\",\"tags\":[\"Cloud\"],\"highestVersion\":true,\"systemName\":\"Cloud\",\"name\":\"Cloud\",\"invariantUuid\":\"ab5263fd-115c-41f2-8d0c-8b9279bce2b2\",\"UUID\":\"208cf7df-68a1-4ae7-afc9-409ea8012332\",\"normalizedName\":\"cloud\",\"toscaResourceName\":\"org.openecomp.resource.Endpoint.Cloud\",\"uniqueId\":\"9674e7e1-bc1a-41fe-b503-fbe996801475\",\"resourceType\":\"VFC\"}";
+        when(property.value()).thenReturn(vertexJsonIsDeletedNotFound);
+        List<CatalogComponent> componentList = toscaOperation.getElementCatalogData(true, null).left().value();
+        assertEquals(1, componentList.size());
+    }
+
+    @Test
+    public void getComponentFromCatalogWhenDeleteIsFalse() {
+        final String vertexJsonIsDeletedFalse = "{\"lifecycleState\":\"CERTIFIED\",\"componentType\":\"RESOURCE\",\"vendorRelease\":\"1\",\"contactId\":\"ah7840\",\"lastUpdateDate\":1496119811038,\"icon\":\"att\",\"description\":\"Cloud\",\"creationDate\":1459432094781,\"vendorName\":\"AT&T\",\"mandatory\":false,\"version\":\"1.0\",\"tags\":[\"Cloud\"],\"highestVersion\":true,\"systemName\":\"Cloud\",\"name\":\"Cloud\",\"isDeleted\":false,\"invariantUuid\":\"ab5263fd-115c-41f2-8d0c-8b9279bce2b2\",\"UUID\":\"208cf7df-68a1-4ae7-afc9-409ea8012332\",\"normalizedName\":\"cloud\",\"toscaResourceName\":\"org.openecomp.resource.Endpoint.Cloud\",\"uniqueId\":\"9674e7e1-bc1a-41fe-b503-fbe996801475\",\"resourceType\":\"VFC\"}";
+        when(property.value()).thenReturn(vertexJsonIsDeletedFalse);
+        List<CatalogComponent> componentList = toscaOperation.getElementCatalogData(true, null).left().value();
+        assertEquals(1, componentList.size());
+    }
+}
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationTest.java
index 054e71a..9f8d015 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationTest.java
@@ -1,14 +1,6 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import fj.data.Either;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
@@ -28,7 +20,10 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import fj.data.Either;
+import java.util.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Created by chaya on 6/12/2017.
@@ -42,10 +37,10 @@
     private boolean isInitialized = false;
 
     @javax.annotation.Resource
-    ToscaElementOperationTestImpl toscaElementOperation;
+    private ToscaElementOperationTestImpl toscaElementOperation;
 
     @javax.annotation.Resource
-    TitanDao titanDao;
+    private TitanDao titanDao;
 
     @BeforeClass
     public static void initTest(){
@@ -271,7 +266,7 @@
     }
 
     private void initGraphForTest() {
-		GraphTestUtils.createRootCatalogVertex(titanDao);
+        GraphTestUtils.createRootCatalogVertex(titanDao);
 
         Map<GraphPropertyEnum, Object> highstVerticesProps = new HashMap<GraphPropertyEnum, Object>() {
             {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationTestImpl.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationTestImpl.java
index da3ae71..27fbce4 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationTestImpl.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaElementOperationTestImpl.java
@@ -1,5 +1,6 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
@@ -8,8 +9,6 @@
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 
-import fj.data.Either;
-
 /**
  * Created by cb478c on 6/13/2017.
  */
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadePoliciesTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadePoliciesTest.java
index 9b31b0b..0568830 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadePoliciesTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadePoliciesTest.java
@@ -1,16 +1,6 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import static java.util.Arrays.asList;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
+import fj.data.Either;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -19,12 +9,8 @@
 import org.openecomp.sdc.be.dao.config.TitanSpringConfig;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
-import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType;
-import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
-import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
-import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.ComponentParametersView;
 import org.openecomp.sdc.be.model.ModelTestBase;
@@ -35,14 +21,21 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import fj.data.Either;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertTrue;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(classes = {TitanSpringConfig.class, ModelOperationsSpringConfig.class})
 public class ToscaOperationFacadePoliciesTest extends ModelTestBase {
 
-    private static final String CONTAINER_ID = "containerId";
-    private static final String CONTAINER_NAME = "containerName";
     @Autowired
     private ToscaOperationFacade toscaOperationFacade;
     @Autowired
@@ -126,11 +119,7 @@
     }
 
     private void createContainerVertexInDB() {
-        GraphVertex resource = new GraphVertex(VertexTypeEnum.TOPOLOGY_TEMPLATE);
-        resource.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, CONTAINER_ID);
-        resource.addMetadataProperty(GraphPropertyEnum.NAME, CONTAINER_NAME);
-        resource.setJsonMetadataField(JsonPresentationFields.NAME, CONTAINER_NAME);
-        resource.setJsonMetadataField(JsonPresentationFields.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
+        GraphVertex resource = createBasicContainerGraphVertex();
         Either<GraphVertex, TitanOperationStatus> container = titanDao.createVertex(resource);
         assertTrue(container.isLeft());
     }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadeTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadeTest.java
index 46ef5f3..851800d 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadeTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadeTest.java
@@ -1,19 +1,6 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyMap;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
+import fj.data.Either;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -21,7 +8,7 @@
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
@@ -37,7 +24,17 @@
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 
-import fj.data.Either;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ToscaOperationFacadeTest {
@@ -106,73 +103,73 @@
     
     @Test
     public void associatePolicyToComponentSuccessTest(){
-    	Either<PolicyDefinition, StorageOperationStatus> result = associatePolicyToComponentWithStatus(StorageOperationStatus.OK);
-    	assertTrue(result.isLeft());
+        Either<PolicyDefinition, StorageOperationStatus> result = associatePolicyToComponentWithStatus(StorageOperationStatus.OK);
+        assertTrue(result.isLeft());
     }
 
-	@Test
+    @Test
     public void associatePolicyToComponentFailureTest(){
-		Either<PolicyDefinition, StorageOperationStatus> result = associatePolicyToComponentWithStatus(StorageOperationStatus.BAD_REQUEST);
-    	assertTrue(result.isRight() && result.right().value() == StorageOperationStatus.BAD_REQUEST);
+        Either<PolicyDefinition, StorageOperationStatus> result = associatePolicyToComponentWithStatus(StorageOperationStatus.BAD_REQUEST);
+        assertTrue(result.isRight() && result.right().value() == StorageOperationStatus.BAD_REQUEST);
     }
 
     @Test
     public void updatePolicyOfComponentSuccessTest(){
-    	Either<PolicyDefinition, StorageOperationStatus> result = updatePolicyOfComponentWithStatus(StorageOperationStatus.OK);
-    	assertTrue(result.isLeft());
+        Either<PolicyDefinition, StorageOperationStatus> result = updatePolicyOfComponentWithStatus(StorageOperationStatus.OK);
+        assertTrue(result.isLeft());
     }
 
-	@Test
+    @Test
     public void updatePolicyOfComponentFailureTest(){
-		Either<PolicyDefinition, StorageOperationStatus> result = updatePolicyOfComponentWithStatus(StorageOperationStatus.NOT_FOUND);
-    	assertTrue(result.isRight() && result.right().value() == StorageOperationStatus.NOT_FOUND);
+        Either<PolicyDefinition, StorageOperationStatus> result = updatePolicyOfComponentWithStatus(StorageOperationStatus.NOT_FOUND);
+        assertTrue(result.isRight() && result.right().value() == StorageOperationStatus.NOT_FOUND);
     }
     
     @Test
     public void removePolicyFromComponentSuccessTest(){
-    	removePolicyFromComponentWithStatus(StorageOperationStatus.OK);
+        removePolicyFromComponentWithStatus(StorageOperationStatus.OK);
     }
     
     @Test
     public void removePolicyFromComponentFailureTest(){
-    	removePolicyFromComponentWithStatus(StorageOperationStatus.NOT_FOUND);
+        removePolicyFromComponentWithStatus(StorageOperationStatus.NOT_FOUND);
     }
     
     private Either<PolicyDefinition, StorageOperationStatus> associatePolicyToComponentWithStatus(StorageOperationStatus status) {
-    	PolicyDefinition policy = new PolicyDefinition();
-    	String componentId = "componentId";
-    	int counter = 0;
-    	GraphVertex vertex;
-    	if(status == StorageOperationStatus.OK){
-    		vertex = getTopologyTemplateVertex();
-    	} else {
-    		vertex = getNodeTypeVertex();
-    	}
-    	Either<GraphVertex, TitanOperationStatus> getVertexEither = Either.left(vertex);
-    	when(titanDaoMock.getVertexById(eq(componentId), eq(JsonParseFlagEnum.ParseMetadata))).thenReturn(getVertexEither);
-    	when(topologyTemplateOperationMock.addPolicyToToscaElement(eq(vertex), any(PolicyDefinition.class), anyInt())).thenReturn(status);
-    	return testInstance.associatePolicyToComponent(componentId, policy, counter);
+        PolicyDefinition policy = new PolicyDefinition();
+        String componentId = "componentId";
+        int counter = 0;
+        GraphVertex vertex;
+        if(status == StorageOperationStatus.OK){
+            vertex = getTopologyTemplateVertex();
+        } else {
+            vertex = getNodeTypeVertex();
+        }
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = Either.left(vertex);
+        when(titanDaoMock.getVertexById(eq(componentId), eq(JsonParseFlagEnum.ParseMetadata))).thenReturn(getVertexEither);
+        when(topologyTemplateOperationMock.addPolicyToToscaElement(eq(vertex), any(PolicyDefinition.class), anyInt())).thenReturn(status);
+        return testInstance.associatePolicyToComponent(componentId, policy, counter);
     }
     
     private Either<PolicyDefinition, StorageOperationStatus> updatePolicyOfComponentWithStatus(StorageOperationStatus status) {
-    	PolicyDefinition policy = new PolicyDefinition();
-    	String componentId = "componentId";
-    	GraphVertex vertex = getTopologyTemplateVertex();
-    	when(titanDaoMock.getVertexById(eq(componentId), eq(JsonParseFlagEnum.NoParse))).thenReturn(Either.left(vertex));
-    	when(topologyTemplateOperationMock.updatePolicyOfToscaElement(eq(vertex), any(PolicyDefinition.class))).thenReturn(status);
-    	return testInstance.updatePolicyOfComponent(componentId, policy);
+        PolicyDefinition policy = new PolicyDefinition();
+        String componentId = "componentId";
+        GraphVertex vertex = getTopologyTemplateVertex();
+        when(titanDaoMock.getVertexById(eq(componentId), eq(JsonParseFlagEnum.NoParse))).thenReturn(Either.left(vertex));
+        when(topologyTemplateOperationMock.updatePolicyOfToscaElement(eq(vertex), any(PolicyDefinition.class))).thenReturn(status);
+        return testInstance.updatePolicyOfComponent(componentId, policy);
     }
 
-	private void removePolicyFromComponentWithStatus(StorageOperationStatus status) {
-		String componentId = "componentId";
-    	String policyId = "policyId";
-    	GraphVertex vertex = getTopologyTemplateVertex();
-    	Either<GraphVertex, TitanOperationStatus> getVertexEither = Either.left(vertex);
-    	when(titanDaoMock.getVertexById(eq(componentId), eq(JsonParseFlagEnum.NoParse))).thenReturn(getVertexEither);
-    	when(topologyTemplateOperationMock.removePolicyFromToscaElement(eq(vertex), eq(policyId))).thenReturn(status);
-    	StorageOperationStatus result = testInstance.removePolicyFromComponent(componentId, policyId);
-    	assertTrue(result == status);
-	}
+    private void removePolicyFromComponentWithStatus(StorageOperationStatus status) {
+        String componentId = "componentId";
+        String policyId = "policyId";
+        GraphVertex vertex = getTopologyTemplateVertex();
+        Either<GraphVertex, TitanOperationStatus> getVertexEither = Either.left(vertex);
+        when(titanDaoMock.getVertexById(eq(componentId), eq(JsonParseFlagEnum.NoParse))).thenReturn(getVertexEither);
+        when(topologyTemplateOperationMock.removePolicyFromToscaElement(eq(vertex), eq(policyId))).thenReturn(status);
+        StorageOperationStatus result = testInstance.removePolicyFromComponent(componentId, policyId);
+        assertSame(result, status);
+    }
     
     private List<GraphVertex> getMockVertices(int numOfVertices) {
         return IntStream.range(0, numOfVertices).mapToObj(i -> getTopologyTemplateVertex()).collect(Collectors.toList());
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/UpgradeOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/UpgradeOperationTest.java
new file mode 100644
index 0000000..acb9af6
--- /dev/null
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/UpgradeOperationTest.java
@@ -0,0 +1,183 @@
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import fj.data.Either;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
+import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.model.category.CategoryDefinition;
+import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
+import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
+import org.openecomp.sdc.be.model.jsontitan.utils.GraphTestUtils;
+import org.openecomp.sdc.be.model.operations.api.IElementOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.UserAdminOperation;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("classpath:application-context-test.xml")
+public class UpgradeOperationTest extends ModelTestBase {
+
+    private boolean isInitialized;
+    @Resource
+    private TitanDao titanDao;
+    @Resource
+    private UpgradeOperation upgradeOperation;
+    @Resource
+    private TopologyTemplateOperation topologyTemplateOperation;
+    @Resource
+    private NodeTemplateOperation nodeTemplateOperation;
+    @Resource
+    private UserAdminOperation userAdminOperation; 
+    @javax.annotation.Resource
+    private IElementOperation elementOperation;
+
+    private User user;
+
+    private CategoryDefinition resourceCategory;
+    private CategoryDefinition serviceCategory;
+    
+
+    @BeforeClass
+    public static void initTest() {
+        ModelTestBase.init();
+    }
+
+    @Before
+    public void beforeTest() {
+        if (!isInitialized) {
+            GraphTestUtils.clearGraph(titanDao);
+            initGraphForTest();
+            isInitialized = true;
+        }
+    }
+
+    @Test
+    public void testGetSimpleDependency() {
+        
+        TopologyTemplate vf = createVf("vf1");
+        
+        TopologyTemplate service = createServiceWitnInstance("service1", vf);
+
+        
+        Either<List<ComponentDependency>, StorageOperationStatus> result = upgradeOperation.getComponentDependencies(vf.getUniqueId());
+        assertThat(result.isLeft()).isTrue();
+        List<ComponentDependency> dependencies = result.left().value();
+        assertThat(dependencies).hasSize(1);
+        
+        ComponentDependency dependency = dependencies.get(0);
+        assertThat(dependency.getName()).isEqualTo(vf.getName());
+        assertThat(dependency.getVersion()).isEqualTo(vf.getVersion());
+        assertThat(dependency.getDependencies()).hasSize(1);
+        
+        ComponentDependency container = dependency.getDependencies().get(0);
+        assertThat(container.getName()).isEqualTo(service.getName());
+        assertThat(container.getVersion()).isEqualTo(service.getVersion());
+        assertThat(container.getDependencies()).isNull();
+
+    }
+
+    /*******************************
+     * Preperation Methods
+     *******************************/
+    private void initGraphForTest() {
+
+        user = new User("Jim", "Tom", "jt123a", "1@mail.com", "DESIGNER", System.currentTimeMillis());
+        Either<User, StorageOperationStatus> saveUserData = userAdminOperation.saveUserData(user);
+        assertThat(saveUserData.isLeft()).isTrue();
+        
+        GraphTestUtils.createRootCatalogVertex(titanDao);
+        resourceCategory = createResourceCategories();
+        serviceCategory = createServiceCategory(); 
+        
+    }
+
+    private TopologyTemplate createServiceWitnInstance(String name, TopologyTemplate createdVf) {
+        
+        TopologyTemplate serviceNew = createTopologyTemplate(ComponentTypeEnum.SERVICE, name);
+        List<CategoryDefinition> categoriesService = new ArrayList<>();
+        categoriesService.add(serviceCategory);
+        serviceNew.setCategories(categoriesService);
+
+        Either<TopologyTemplate, StorageOperationStatus> createService = topologyTemplateOperation.createTopologyTemplate(serviceNew);
+        assertThat(createService.isLeft()).isTrue();
+        
+        ComponentInstance vfInstance = new ComponentInstance();
+        vfInstance.setUniqueId(createdVf.getUniqueId() + createdVf.getName());
+        vfInstance.setComponentUid(createdVf.getUniqueId());
+        vfInstance.setName(createdVf.getName());
+        Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addInstance = nodeTemplateOperation.addComponentInstanceToTopologyTemplate(serviceNew, createdVf, "0", vfInstance, false, user);
+        assertThat(addInstance.isLeft()).isTrue();
+        return serviceNew;
+    }
+
+    private CategoryDefinition createServiceCategory() {
+        CategoryDefinition categoryService = new CategoryDefinition();
+        categoryService.setName("servicecategory");
+        categoryService.setNormalizedName("servicecategory");
+        categoryService.setUniqueId("servicecategory");
+        Either<CategoryDefinition, ActionStatus> createCategory = elementOperation.createCategory(categoryService , NodeTypeEnum.ServiceNewCategory);
+        
+        assertThat(createCategory.isLeft()).isTrue();
+        return categoryService;
+    }
+
+    private TopologyTemplate createVf(String name) {
+        
+        TopologyTemplate resource = createTopologyTemplate(ComponentTypeEnum.RESOURCE, name);
+
+        resource.setResourceType(ResourceTypeEnum.VF);
+        List<CategoryDefinition> categories = new ArrayList<>();
+        categories.add(resourceCategory);
+        resource.setCategories(categories);
+        Either<TopologyTemplate, StorageOperationStatus> createVf = topologyTemplateOperation.createTopologyTemplate(resource);
+        assertThat( createVf.isLeft()).isTrue();
+        return resource;
+    }
+
+    private CategoryDefinition createResourceCategories() {
+        CategoryDefinition category = new CategoryDefinition();
+        category.setName("category1");
+        category.setNormalizedName("category1");
+        category.setUniqueId("category1");
+        Either<CategoryDefinition, ActionStatus> createCategory = elementOperation.createCategory(category , NodeTypeEnum.ResourceNewCategory);
+        assertThat(createCategory.isLeft()).isTrue();
+        
+        SubCategoryDefinition subCategory = new SubCategoryDefinition();
+        
+        subCategory.setName("subcategory1");
+        subCategory.setNormalizedName("subcategory1");
+        subCategory.setUniqueId("subcategory1");
+        elementOperation.createSubCategory(createCategory.left().value().getUniqueId(), subCategory, NodeTypeEnum.ResourceSubcategory);
+        category.addSubCategory(subCategory);
+        return category;
+    }
+
+    private TopologyTemplate createTopologyTemplate(ComponentTypeEnum type, String name) {
+        TopologyTemplate template = new TopologyTemplate();
+        template.setUniqueId(IdBuilderUtils.generateUniqueId());
+        template.setComponentType(type);
+        template.setHighestVersion(true);
+        template.setLifecycleState(LifecycleStateEnum.CERTIFIED);
+        template.setMetadataValue(JsonPresentationFields.NAME, name);
+        template.setMetadataValue(JsonPresentationFields.VERSION, "1.0");
+        template.setCreatorUserId(user.getUserId());
+        return template;
+    }
+}
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/GraphTestUtils.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/GraphTestUtils.java
index 72919b6..71dd472 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/GraphTestUtils.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/GraphTestUtils.java
@@ -20,14 +20,9 @@
 
 package org.openecomp.sdc.be.model.jsontitan.utils;
 
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.UUID;
-
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.tinkerpop.gremlin.structure.io.IoCore;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
@@ -38,18 +33,29 @@
 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
 
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.thinkaurelius.titan.core.TitanVertex;
-
-import fj.data.Either;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
 
 public final class GraphTestUtils {
 
-	public static void createRootCatalogVertex(TitanDao titanDao) {
-		GraphVertex catalogRootVertex = new GraphVertex(VertexTypeEnum.CATALOG_ROOT);
-		catalogRootVertex.setUniqueId(IdBuilderUtils.generateUniqueId());
-		titanDao.createVertex(catalogRootVertex);
-	}
+    public static GraphVertex createRootCatalogVertex(TitanDao titanDao) {
+        GraphVertex catalogRootVertex = new GraphVertex(VertexTypeEnum.CATALOG_ROOT);
+        catalogRootVertex.setUniqueId(IdBuilderUtils.generateUniqueId());
+        return titanDao.createVertex(catalogRootVertex)
+                .either(v -> v, s -> null);
+    }
+
+    public static GraphVertex createRootArchiveVertex(TitanDao titanDao) {
+        GraphVertex archiveRootVertex = new GraphVertex(VertexTypeEnum.ARCHIVE_ROOT);
+        archiveRootVertex.setUniqueId(IdBuilderUtils.generateUniqueId());
+        return titanDao.createVertex(archiveRootVertex)
+                .either(v -> v, s -> null);
+    }
 
     public static GraphVertex createResourceVertex(TitanDao titanDao, Map<GraphPropertyEnum,Object> metadataProps, ResourceTypeEnum type) {
         GraphVertex vertex = new GraphVertex();
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/InterfaceUtilsTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/InterfaceUtilsTest.java
index 9a7ccc7..9d44232 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/InterfaceUtilsTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/InterfaceUtilsTest.java
@@ -1,15 +1,15 @@
 package org.openecomp.sdc.be.model.jsontitan.utils;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.Operation;
 import org.openecomp.sdc.be.model.Resource;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
 public class InterfaceUtilsTest {
 
 	private InterfaceUtils createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/JsonObjectTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/JsonObjectTest.java
index b347652..a201b30 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/JsonObjectTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/JsonObjectTest.java
@@ -20,57 +20,56 @@
 
 package org.openecomp.sdc.be.model.operations;
 
-import static org.junit.Assert.assertEquals;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.Before;
 import org.junit.Test;
 import org.openecomp.sdc.be.model.UploadResourceInfo;
 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
 import org.openecomp.sdc.common.api.UploadArtifactInfo;
 
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import static org.junit.Assert.assertEquals;
 
 public class JsonObjectTest {
 
-	private ObjectMapper mapper;
-	UploadResourceInfo inputObjectRef;
-	private final String INPUT_RESOURCE_STRING = "{  \"payloadData\" : \"My Test Object\",  \"payloadName\" : \"TestName\", " + "  \"description\":\"my_description\",\"tags\":[\"tag1\"], "
-			+ "\"artifactList\" : [ {    \"artifactName\" : \"myArtifact0\",  \"artifactPath\" : \"scripts/\",  \"artifactType\" : \"PUPPET\",   " + " \"artifactDescription\" : \"This is Description\",    \"artifactData\" : null  }, "
-			+ "{    \"artifactName\" : \"myArtifact1\",  \"artifactPath\" : \"scripts/\", \"artifactType\" : \"PUPPET\",    \"artifactDescription\" : \"This is Description\", "
-			+ "   \"artifactData\" : null  } ], \"contactId\" : null, \"name\" : null, \"resourceIconPath\" : null, \"vendorName\" : null, \"vendorRelease\" : null , \"resourceType\" : \"VFC\" }";
+    private ObjectMapper mapper;
+    UploadResourceInfo inputObjectRef;
+    private final String INPUT_RESOURCE_STRING = "{  \"payloadData\" : \"My Test Object\",  \"payloadName\" : \"TestName\", " + "  \"description\":\"my_description\",\"tags\":[\"tag1\"], "
+            + "\"artifactList\" : [ {    \"artifactName\" : \"myArtifact0\",  \"artifactPath\" : \"scripts/\",  \"artifactType\" : \"PUPPET\",   " + " \"artifactDescription\" : \"This is Description\",    \"artifactData\" : null  }, "
+            + "{    \"artifactName\" : \"myArtifact1\",  \"artifactPath\" : \"scripts/\", \"artifactType\" : \"PUPPET\",    \"artifactDescription\" : \"This is Description\", "
+            + "   \"artifactData\" : null  } ], \"contactId\" : null, \"name\" : null, \"resourceIconPath\" : null, \"vendorName\" : null, \"vendorRelease\" : null , \"resourceType\" : \"VFC\" }";
 
-	@Before
-	public void setup() {
-		mapper = new ObjectMapper();
-		ArrayList<UploadArtifactInfo> artifactList = new ArrayList<UploadArtifactInfo>();
-		for (int i = 0; i < 2; i++) {
-			UploadArtifactInfo artifactInfo = new UploadArtifactInfo("myArtifact" + i, "scripts/", ArtifactTypeEnum.PUPPET, "This is Description");
-			artifactList.add(artifactInfo);
-		}
-		ArrayList<String> tags = new ArrayList<>();
-		tags.add("tag1");
-		inputObjectRef = new UploadResourceInfo("My Test Object", "TestName", "my_description", null, tags, artifactList);
+    @Before
+    public void setup() {
+        mapper = new ObjectMapper();
+        ArrayList<UploadArtifactInfo> artifactList = new ArrayList<>();
+        for (int i = 0; i < 2; i++) {
+            UploadArtifactInfo artifactInfo = new UploadArtifactInfo("myArtifact" + i, "scripts/", ArtifactTypeEnum.PUPPET, "This is Description");
+            artifactList.add(artifactInfo);
+        }
+        ArrayList<String> tags = new ArrayList<>();
+        tags.add("tag1");
+        inputObjectRef = new UploadResourceInfo("My Test Object", "TestName", "my_description", null, tags, artifactList);
 
-	}
+    }
 
-	@Test
-	public void testStringToUploadResourceInfo() throws JsonParseException, JsonMappingException, IOException {
-		UploadResourceInfo resourceObjectTest = mapper.readValue(INPUT_RESOURCE_STRING, UploadResourceInfo.class);
-		assertEquals(inputObjectRef, resourceObjectTest);
+    @Test
+    public void testStringToUploadResourceInfo() throws JsonParseException, JsonMappingException, IOException {
+        UploadResourceInfo resourceObjectTest = mapper.readValue(INPUT_RESOURCE_STRING, UploadResourceInfo.class);
+        assertEquals(inputObjectRef, resourceObjectTest);
 
-	}
+    }
 
-	// @Test
-	public void testUploadResourceInfoToString() throws JsonParseException, JsonMappingException, IOException {
-		String refAsString = mapper.writeValueAsString(inputObjectRef);
-		String unFormattedString = refAsString.replace("\n", "").replace("\t", "").replace(" ", "");
+    // @Test
+    public void testUploadResourceInfoToString() throws JsonParseException, JsonMappingException, IOException {
+        String refAsString = mapper.writeValueAsString(inputObjectRef);
+        String unFormattedString = refAsString.replace("\n", "").replace("\t", "").replace(" ", "");
 
-		assertEquals(unFormattedString, INPUT_RESOURCE_STRING.replace("\n", "").replace("\t", "").replace(" ", ""));
+        assertEquals(unFormattedString, INPUT_RESOURCE_STRING.replace("\n", "").replace("\t", "").replace(" ", ""));
 
-	}
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperationTest.java
index f68da59..d59b810 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperationTest.java
@@ -20,8 +20,6 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import static org.junit.Assert.assertTrue;
-
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -35,56 +33,59 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:application-context-test.xml")
 public class AdditionalInformationOperationTest extends ModelTestBase {
 
-	private static String USER_ID = "muUserId";
-	private static String CATEGORY_NAME = "category/mycategory";
+    private static String USER_ID = "muUserId";
+    private static String CATEGORY_NAME = "category/mycategory";
 
-	@javax.annotation.Resource(name = "titan-generic-dao")
-	private TitanGenericDao titanDao;
+    @javax.annotation.Resource(name = "titan-generic-dao")
+    private TitanGenericDao titanDao;
 
-	@javax.annotation.Resource(name = "additional-information-operation")
-	private IAdditionalInformationOperation additionalInformationOperation;
+    @javax.annotation.Resource(name = "additional-information-operation")
+    private IAdditionalInformationOperation additionalInformationOperation;
 
-	@Before
-	public void createUserAndCategory() {
-		deleteAndCreateCategory(CATEGORY_NAME);
-		deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID);
+    @Before
+    public void createUserAndCategory() {
+        deleteAndCreateCategory(CATEGORY_NAME);
+        deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID);
 
-	}
+    }
 
-	@BeforeClass
-	public static void setupBeforeClass() {
+    @BeforeClass
+    public static void setupBeforeClass() {
 
-		ModelTestBase.init();
+        ModelTestBase.init();
 
-	}
+    }
 
-	@Test
-	public void testDummy() {
+    @Test
+    public void testDummy() {
 
-		assertTrue(additionalInformationOperation != null);
+        assertNotNull(additionalInformationOperation);
 
-	}
+    }
 
-	private UserData deleteAndCreateUser(String userId, String firstName, String lastName) {
-		UserData userData = new UserData();
-		userData.setUserId(userId);
-		userData.setFirstName(firstName);
-		userData.setLastName(lastName);
+    private UserData deleteAndCreateUser(String userId, String firstName, String lastName) {
+        UserData userData = new UserData();
+        userData.setUserId(userId);
+        userData.setFirstName(firstName);
+        userData.setLastName(lastName);
 
-		titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class);
-		titanDao.createNode(userData, UserData.class);
-		titanDao.commit();
+        titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class);
+        titanDao.createNode(userData, UserData.class);
+        titanDao.commit();
 
-		return userData;
-	}
+        return userData;
+    }
 
-	private void deleteAndCreateCategory(String category) {
-		String[] names = category.split("/");
-		OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao);
-	}
+    private void deleteAndCreateCategory(String category) {
+        String[] names = category.split("/");
+        OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao);
+    }
 
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AnnotationTypeOperationsTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AnnotationTypeOperationsTest.java
new file mode 100644
index 0000000..9a3c666
--- /dev/null
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AnnotationTypeOperationsTest.java
@@ -0,0 +1,197 @@
+package org.openecomp.sdc.be.model.operations.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
+import org.openecomp.sdc.be.model.AnnotationTypeDefinition;
+import org.openecomp.sdc.be.model.ModelTestBase;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.operations.StorageException;
+import org.openecomp.sdc.be.utils.TypeUtils;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.annotation.Resource;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("classpath:application-context-test.xml")
+public class AnnotationTypeOperationsTest extends ModelTestBase {
+
+    static final String TYPE = "org.openecomp.annotations.source";
+    static final String NEW_TYPE = "org.openecomp.annotations.Source";
+    static final String DESCRIPTION = "description";
+    static final String NEW_DESCRIPTION = "new description";
+
+    @Resource
+    private TitanGenericDao titanGenericDao;
+
+    @Resource
+    private CommonTypeOperations commonTypeOperations;
+
+    @Resource
+    private AnnotationTypeOperations annotationTypeOperations;
+
+    private PropertyDefinition prop1, prop2;
+    private AnnotationTypeDefinition initialAnnotationDefinition;
+
+    @BeforeClass
+    public static void setupBeforeClass() {
+        ModelTestBase.init();
+    }
+
+    @Before
+    public void initTestData() {
+        removeGraphVertices(titanGenericDao.getGraph());
+        prop1 = createSimpleProperty("val1", "prop1", "string");
+    }
+
+    @After
+    public void tearDown() {
+        titanGenericDao.rollback();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testAddType() {
+        prepareInitialType();
+        AnnotationTypeDefinition result = annotationTypeOperations.addType(initialAnnotationDefinition);
+        assertThat(result.getUniqueId()).isNotEmpty();
+        assertThat(result)
+                .isEqualToComparingOnlyGivenFields(initialAnnotationDefinition, "description", "type");
+        assertThat(result.getProperties())
+                .usingElementComparatorOnFields("defaultValue", "name", "type")
+                .containsExactlyInAnyOrder(prop1);
+        assertThat(result.isHighestVersion()).isTrue();
+    }
+
+   @Test
+    public void testGetLatestType_TypeDoesntExist_shouldReturnNull() {
+        AnnotationTypeDefinition latestType = annotationTypeOperations.getLatestType(TYPE);
+        assertThat(latestType).isNull();
+    }
+
+    @Test
+    public void testGetLatestType_TypeExists_shouldReturnIt() {
+        addAnnotationType();
+        AnnotationTypeDefinition latestType = annotationTypeOperations.getLatestType(TYPE);
+        assertThat(latestType.getType()).isEqualTo(TYPE);
+    }
+
+    public void addAnnotationType() {
+        prepareInitialType();
+        annotationTypeOperations.addType(initialAnnotationDefinition);
+        titanGenericDao.commit();
+    }
+
+    @Test
+    public void compareTypes_same_shouldReturnTrue() {
+        AnnotationTypeDefinition type1 = buildAnnotationDefinition(DESCRIPTION, TYPE, prop1);
+        AnnotationTypeDefinition type2 = buildAnnotationDefinition(DESCRIPTION, TYPE, prop1);
+        assertThat(annotationTypeOperations.isSameType(type1, type2)).isTrue();
+    }
+
+    @Test
+    public void compareTypes_sameExceptVersions_shouldReturnTrue() {
+        AnnotationTypeDefinition type1 = buildAnnotationDefinition(DESCRIPTION, TYPE, prop1);
+        AnnotationTypeDefinition type2 = buildAnnotationDefinition(DESCRIPTION, TYPE, prop1);
+        type1.setVersion("1");
+        type2.setVersion("2");
+        assertThat(annotationTypeOperations.isSameType(type1, type2)).isTrue();
+    }
+
+    @Test
+    public void compareTypes_differentType_shouldReturnFalse() {
+        AnnotationTypeDefinition type1 = buildAnnotationDefinition(DESCRIPTION, TYPE, prop1);
+        AnnotationTypeDefinition type2 = buildAnnotationDefinition(DESCRIPTION, NEW_TYPE, prop1);
+        assertThat(annotationTypeOperations.isSameType(type1, type2)).isFalse();
+    }
+
+    @Test
+    public void compareTypes_differentDescription_shouldReturnFalse() {
+        AnnotationTypeDefinition type1 = buildAnnotationDefinition(DESCRIPTION, TYPE, prop1);
+        AnnotationTypeDefinition type2 = buildAnnotationDefinition(NEW_DESCRIPTION, TYPE, prop1);
+        assertThat(annotationTypeOperations.isSameType(type1, type2)).isFalse();
+    }
+
+    @Test
+    public void compareTypes_differentProperty_shouldReturnFalse() {
+        AnnotationTypeDefinition type1 = buildAnnotationDefinition(DESCRIPTION, TYPE, prop1);
+        prop2 = createSimpleProperty("val2", "prop2", "string");
+        AnnotationTypeDefinition type2 = buildAnnotationDefinition(DESCRIPTION, TYPE, prop2);
+        assertThat(annotationTypeOperations.isSameType(type1, type2)).isFalse();
+    }
+
+    @Test
+    public void testUpdateType_propertyAdded_shouldSucceed() {
+        addAnnotationType();
+        prop2 = createSimpleProperty("val2", "prop2", "string");
+        AnnotationTypeDefinition advancedDefinition = buildAnnotationDefinition(NEW_DESCRIPTION, TYPE, prop1, prop2);
+        AnnotationTypeDefinition updatedType = annotationTypeOperations.updateType(initialAnnotationDefinition, advancedDefinition);
+        assertThat(updatedType.getDescription()).isEqualTo(NEW_DESCRIPTION);
+        assertThat(updatedType.getProperties())
+                .usingElementComparatorOnFields("defaultValue", "name", "type")
+                .containsExactlyInAnyOrder(prop1, prop2);
+    }
+
+    @Test
+    public void testUpdateType_propertyDefaultValueModification_shouldSucceed() {
+        addAnnotationType();
+        prop2 = createSimpleProperty("val3", "prop1", "string");
+        AnnotationTypeDefinition advancedDefinition = buildAnnotationDefinition(DESCRIPTION, TYPE, prop2);
+        AnnotationTypeDefinition updatedType = annotationTypeOperations.updateType(initialAnnotationDefinition, advancedDefinition);
+        assertThat(updatedType.getProperties())
+                .usingElementComparatorOnFields("defaultValue", "name", "type")
+                .containsExactlyInAnyOrder(prop2);
+    }
+
+    @Test
+    public void testUpdateType_propertyDescriptionModification_shouldSucceed() {
+        addAnnotationType();
+        prop2 = createSimpleProperty("val1", "prop1", "string");
+        prop2.setDescription("bla");
+        AnnotationTypeDefinition advancedDefinition = buildAnnotationDefinition(DESCRIPTION, TYPE, prop2);
+        AnnotationTypeDefinition updatedType = annotationTypeOperations.updateType(initialAnnotationDefinition, advancedDefinition);
+        assertThat(updatedType.getProperties())
+                .usingElementComparatorOnFields("defaultValue", "name", "type", "description")
+                .containsExactlyInAnyOrder(prop2);
+    }
+
+    @Test(expected = StorageException.class)
+    public void testUpdateType_propertyTypeModification_shouldFail() {
+        addAnnotationType();
+        prop2 = createSimpleProperty("val1", "prop1", "int");
+        AnnotationTypeDefinition advancedDefinition = buildAnnotationDefinition(DESCRIPTION, TYPE, prop2);
+        annotationTypeOperations.updateType(initialAnnotationDefinition, advancedDefinition);
+    }
+
+    @Test(expected = StorageException.class)
+    public void testUpdateType_propertyRemoved_shouldFail() {
+        addAnnotationType();
+        prop2 = createSimpleProperty("val1", "prop2", "int");
+        AnnotationTypeDefinition advancedDefinition = buildAnnotationDefinition(DESCRIPTION, TYPE, prop2);
+        annotationTypeOperations.updateType(initialAnnotationDefinition, advancedDefinition);
+    }
+
+    private void prepareInitialType() {
+        initialAnnotationDefinition = buildAnnotationDefinition(DESCRIPTION,
+                TYPE,
+                prop1);
+        initialAnnotationDefinition.setVersion(TypeUtils.FIRST_CERTIFIED_VERSION_VERSION);
+    }
+
+    private AnnotationTypeDefinition buildAnnotationDefinition(String description, String type, PropertyDefinition ... properties) {
+        AnnotationTypeDefinition annotationTypeDefinition = new AnnotationTypeDefinition();
+        annotationTypeDefinition.setDescription(description);
+        annotationTypeDefinition.setType(type);
+        annotationTypeDefinition.setHighestVersion(true);
+        annotationTypeDefinition.setProperties(asList(properties));
+        return annotationTypeDefinition;
+    }
+
+}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperationTest.java
index cd4433a..8e92549 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperationTest.java
@@ -32,20 +32,12 @@
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-import org.openecomp.sdc.be.model.HeatParameterDefinition;
-import org.openecomp.sdc.be.model.LifecycleStateEnum;
-import org.openecomp.sdc.be.model.ModelTestBase;
-import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.util.OperationTestsUtil;
-import org.openecomp.sdc.be.resources.data.ArtifactData;
-import org.openecomp.sdc.be.resources.data.HeatParameterData;
-import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
-import org.openecomp.sdc.be.resources.data.UniqueIdData;
-import org.openecomp.sdc.be.resources.data.UserData;
+import org.openecomp.sdc.be.resources.data.*;
 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -57,7 +49,7 @@
 import java.util.List;
 import java.util.Map;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -66,439 +58,346 @@
 @ContextConfiguration("classpath:application-context-test.xml")
 public class ArtifactOperationTest extends ModelTestBase {
 
-	private static final String ARTIFACT_NAME = "myHeatArtifact";
+    private static final String ARTIFACT_NAME = "myHeatArtifact";
 
-	@javax.annotation.Resource(name = "titan-generic-dao")
-	private TitanGenericDao titanDao;
+    @javax.annotation.Resource(name = "titan-generic-dao")
+    private TitanGenericDao titanDao;
 
-	@javax.annotation.Resource(name = "tosca-operation-facade")
-	private ToscaOperationFacade toscaOperationFacade;
+    @javax.annotation.Resource(name = "tosca-operation-facade")
+    private ToscaOperationFacade toscaOperationFacade;
 
-	@javax.annotation.Resource
-	private ArtifactOperation artifactOperation;
+    @javax.annotation.Resource
+    private ArtifactOperation artifactOperation;
 
-	private static Logger log = LoggerFactory.getLogger(ToscaOperationFacade.class.getName());
+    private static final Logger log = LoggerFactory.getLogger(ToscaOperationFacade.class);
 
-	private static String RESOURCE_ID = "resourceId";
-	private static String RESOURCE_ID_2 = "resourceId2";
+    private static String RESOURCE_ID = "resourceId";
+    private static String RESOURCE_ID_2 = "resourceId2";
 
-	private static String USER_ID = "muUserId";
-	private static String CATEGORY_NAME = "category/mycategory";
+    private static String USER_ID = "muUserId";
+    private static String CATEGORY_NAME = "category/mycategory";
 
-	@BeforeClass
-	public static void setupBeforeClass() {
+    @BeforeClass
+    public static void setupBeforeClass() {
 
-		ModelTestBase.init();
-	}
+        ModelTestBase.init();
+    }
 
-	@Before
-	public void createUserAndCategory() {
-		deleteAndCreateCategory(CATEGORY_NAME);
-		deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID, null);
-	}
+    @Before
+    public void createUserAndCategory() {
+        deleteAndCreateCategory(CATEGORY_NAME);
+        deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID, null);
+    }
 
-	@Test
-	@Ignore
-	public void testAddArtifactToServiceVersionAndUUIDNotNull() {
-		CategoryDefinition category = new CategoryDefinition();
-		category.setName(CATEGORY_NAME);
+    @Test
+    public void testCreateDeleteArtifactWithHeatParams() {
 
-		String serviceName = "servceTest2";
-		String serviceVersion = "0.1";
-		String userId = USER_ID;
-		Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true);
-		log.debug("{}", serviceAfterSave);
-		String serviceId = serviceAfterSave.getUniqueId();
+        ArtifactDefinition artifactWithHeat = createResourceWithHeat();
 
-		ArtifactDefinition artifactInfo = addArtifactToService(userId, serviceId, "install_apache");
+        List<HeatParameterDefinition> heatParameters = artifactWithHeat.getListHeatParameters();
+        assertNotNull(heatParameters);
+        assertEquals(1, heatParameters.size());
+        HeatParameterDefinition parameter = heatParameters.get(0);
+        HeatParameterData parameterData = new HeatParameterData(parameter);
+        Either<HeatParameterData, TitanOperationStatus> parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNode.isLeft());
 
-		assertEquals("add informational artifact version : " + artifactInfo.getArtifactVersion(), "1", artifactInfo.getArtifactVersion());
+        Either<ArtifactDefinition, StorageOperationStatus> removeArifact = artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, true, false);
+        assertTrue(removeArifact.isLeft());
 
-		assertNotNull("add informational artifact version : " + artifactInfo.getArtifactUUID(), artifactInfo.getArtifactUUID());
+        ArtifactData artifactData = new ArtifactData(artifactWithHeat);
+        Either<ArtifactData, TitanOperationStatus> artifactAfterDelete = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
+        assertTrue(artifactAfterDelete.isRight());
 
-		Either<Service, StorageOperationStatus> service = toscaOperationFacade.getToscaFullElement(serviceId);
-		assertTrue(service.isLeft());
+        Either<HeatParameterData, TitanOperationStatus> parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNodeAfterDelete.isRight());
 
-		Map<String, ArtifactDefinition> artifacts = service.left().value().getArtifacts();
-		for (Map.Entry<String, ArtifactDefinition> entry : artifacts.entrySet()) {
-			String artifactId = entry.getValue().getUniqueId();
-			String description = entry.getValue().getDescription();
+        titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class);
+    }
 
-			artifactOperation.removeArifactFromResource(serviceId, artifactId, NodeTypeEnum.Service, true, false);
-		}
-		service = toscaOperationFacade.getToscaFullElement(serviceId);
-		assertTrue(service.isLeft());
+    @Test
+    public void testUpdateArtifactWithHeatParams() {
 
-		artifacts = service.left().value().getArtifacts();
-		assertEquals(0, artifacts.size());
+        ArtifactDefinition artifactWithHeat = createResourceWithHeat();
 
-		Either<Service, StorageOperationStatus> serviceDelete = toscaOperationFacade.deleteToscaComponent(serviceId);
+        List<HeatParameterDefinition> heatParameters = artifactWithHeat.getListHeatParameters();
+        assertNotNull(heatParameters);
+        assertEquals(1, heatParameters.size());
+        HeatParameterDefinition parameter = heatParameters.get(0);
+        HeatParameterData parameterData = new HeatParameterData(parameter);
+        Either<HeatParameterData, TitanOperationStatus> parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNode.isLeft());
 
-		Either<List<ArtifactData>, TitanOperationStatus> byCriteria = titanDao.getByCriteria(NodeTypeEnum.ArtifactRef, null, ArtifactData.class);
-		assertTrue(byCriteria.isRight());
-		assertEquals(TitanOperationStatus.NOT_FOUND, byCriteria.right().value());
+        // update to artifact without params
+        ArtifactDefinition artifactNoParams = createArtifactDefinition(USER_ID, RESOURCE_ID, ARTIFACT_NAME);
+        artifactNoParams.setUniqueId(artifactWithHeat.getUniqueId());
+        artifactNoParams.setArtifactType("HEAT");
+        artifactNoParams.setArtifactVersion("2");
+        artifactNoParams.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
 
-		toscaOperationFacade.deleteToscaComponent(serviceId);
+        Either<ArtifactDefinition, StorageOperationStatus> updateArifact = artifactOperation.updateArifactOnResource(artifactNoParams, RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, false);
+        assertTrue(updateArifact.isLeft());
 
-	}
+        ArtifactData artifactData = new ArtifactData(artifactWithHeat);
+        Either<ArtifactData, TitanOperationStatus> artifactAfterUpdate = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
+        assertTrue(artifactAfterUpdate.isLeft());
+        ArtifactData artifactAfterUpdateValue = artifactAfterUpdate.left().value();
+        assertEquals(artifactNoParams.getArtifactVersion(), artifactAfterUpdateValue.getArtifactDataDefinition()
+                                                                                    .getArtifactVersion());
 
-	@Test
-	@Ignore
-	public void testUpdateArtifactToServiceVersionNotChanged() {
-		CategoryDefinition category = new CategoryDefinition();
-		category.setName(CATEGORY_NAME);
-		String serviceName = "servceTest2";
-		String serviceVersion = "0.1";
-		String userId = USER_ID;
-		Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true);
-		log.debug("{}", serviceAfterSave);
-		String serviceId = serviceAfterSave.getUniqueId();
+        Either<HeatParameterData, TitanOperationStatus> parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNodeAfterDelete.isRight());
 
-		ArtifactDefinition artifactInfo = addArtifactToService(userId, serviceId, "install_apache");
+        artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, true, false);
+        titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class);
+        titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID_2), ResourceMetadataData.class);
+    }
 
-		String version = artifactInfo.getArtifactVersion();
-		String artUuid = artifactInfo.getArtifactUUID();
-		assertEquals("add informational artifact version : " + version, "1", version);
+    @Test
+    public void testUpdateArtifactMetadataWithHeatParams() {
 
-		artifactInfo.setDescription("jghlsk new desfnjdh");
+        ArtifactDefinition artifactWithHeat = createResourceWithHeat();
 
-		Either<ArtifactDefinition, StorageOperationStatus> artifact = artifactOperation.updateArifactOnResource(artifactInfo, serviceId, artifactInfo.getUniqueId(), NodeTypeEnum.Service, false);
-		String newVersion = artifact.left().value().getArtifactVersion();
-		String newArtUuid = artifactInfo.getArtifactUUID();
-		assertEquals("add informational artifact version : " + newVersion, newVersion, version);
-		assertEquals("add informational artifact uuid : " + newArtUuid, newArtUuid, artUuid);
+        List<HeatParameterDefinition> heatParameters = artifactWithHeat.getListHeatParameters();
+        assertNotNull(heatParameters);
+        assertEquals(1, heatParameters.size());
+        HeatParameterDefinition parameter = heatParameters.get(0);
+        HeatParameterData parameterData = new HeatParameterData(parameter);
+        Either<HeatParameterData, TitanOperationStatus> parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNode.isLeft());
 
-		Either<Service, StorageOperationStatus> service = toscaOperationFacade.getToscaFullElement(serviceId);
-		assertTrue(service.isLeft());
+        // update to artifact without params
+        artifactWithHeat.setArtifactVersion("2");
+        artifactWithHeat.setArtifactChecksum(null);
+        artifactWithHeat.setPayloadData(null);
 
-		Map<String, ArtifactDefinition> artifacts = service.left().value().getArtifacts();
-		for (Map.Entry<String, ArtifactDefinition> entry : artifacts.entrySet()) {
-			String artifactId = entry.getValue().getUniqueId();
-			String description = entry.getValue().getDescription();
+        Either<ArtifactDefinition, StorageOperationStatus> updateArifact = artifactOperation.updateArifactOnResource(artifactWithHeat, RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, false);
+        assertTrue(updateArifact.isLeft());
 
-			artifactOperation.removeArifactFromResource(serviceId, artifactId, NodeTypeEnum.Service, true, false);
-		}
-		service = toscaOperationFacade.getToscaFullElement(serviceId);
-		assertTrue(service.isLeft());
+        ArtifactData artifactData = new ArtifactData(artifactWithHeat);
+        Either<ArtifactData, TitanOperationStatus> artifactAfterUpdate = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
+        assertTrue(artifactAfterUpdate.isLeft());
+        ArtifactData artifactAfterUpdateValue = artifactAfterUpdate.left().value();
+        assertEquals(artifactWithHeat.getArtifactVersion(), artifactAfterUpdateValue.getArtifactDataDefinition()
+                                                                                    .getArtifactVersion());
 
-		artifacts = service.left().value().getArtifacts();
-		assertEquals(0, artifacts.size());
+        Either<HeatParameterData, TitanOperationStatus> parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNodeAfterDelete.isLeft());
 
-		Either<Service, StorageOperationStatus> serviceDelete = toscaOperationFacade.deleteToscaComponent(serviceId);
+        Either<ArtifactDefinition, StorageOperationStatus> removeArifact = artifactOperation.removeArifactFromResource(RESOURCE_ID_2, (String) artifactAfterUpdateValue.getUniqueId(), NodeTypeEnum.Resource, true, false);
+        removeArifact = artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, true, false);
+        titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class);
+        titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID_2), ResourceMetadataData.class);
 
-		Either<List<ArtifactData>, TitanOperationStatus> byCriteria = titanDao.getByCriteria(NodeTypeEnum.ArtifactRef, null, ArtifactData.class);
-		assertTrue(byCriteria.isRight());
-		assertEquals(TitanOperationStatus.NOT_FOUND, byCriteria.right().value());
+    }
 
-		toscaOperationFacade.deleteToscaComponent(serviceAfterSave.getUniqueId());
+    @Test
+    public void updateHeatArtifactWithTwoResources() {
+        ArtifactDefinition artifactWithHeat = createResourceWithHeat();
 
-	}
+        ResourceMetadataData resource2 = createResource(RESOURCE_ID_2);
+        Map<String, Object> props = new HashMap<>();
+        props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), ArtifactGroupTypeEnum.DEPLOYMENT.name());
+        Either<GraphRelation, TitanOperationStatus> createRelation = titanDao.createRelation(resource2, new ArtifactData(artifactWithHeat), GraphEdgeLabels.ARTIFACT_REF, props);
+        assertTrue(createRelation.isLeft());
 
-	@Test
-	public void testCreateDeleteArtifactWithHeatParams() {
+        List<HeatParameterDefinition> heatParameters = artifactWithHeat.getListHeatParameters();
+        assertNotNull(heatParameters);
+        assertEquals(1, heatParameters.size());
+        HeatParameterDefinition parameter = heatParameters.get(0);
+        HeatParameterData parameterData = new HeatParameterData(parameter);
+        Either<HeatParameterData, TitanOperationStatus> parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNode.isLeft());
 
-		ArtifactDefinition artifactWithHeat = createResourceWithHeat();
+        ArtifactDefinition atifactToUpdate = new ArtifactDefinition(artifactWithHeat);
 
-		List<HeatParameterDefinition> heatParameters = artifactWithHeat.getListHeatParameters();
-		assertNotNull(heatParameters);
-		assertTrue(heatParameters.size() == 1);
-		HeatParameterDefinition parameter = heatParameters.get(0);
-		HeatParameterData parameterData = new HeatParameterData(parameter);
-		Either<HeatParameterData, TitanOperationStatus> parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNode.isLeft());
+        // update to artifact without params
+        atifactToUpdate.setArtifactVersion("2");
+        atifactToUpdate.setArtifactChecksum(null);
+        atifactToUpdate.setPayloadData(null);
 
-		Either<ArtifactDefinition, StorageOperationStatus> removeArifact = artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, true, false);
-		assertTrue(removeArifact.isLeft());
+        HeatParameterDefinition heatParamUpdate = new HeatParameterDefinition(parameter);
+        List<HeatParameterDefinition> heatParametersUpdated = new ArrayList<>();
+        heatParamUpdate.setCurrentValue("55");
+        heatParametersUpdated.add(heatParamUpdate);
+        atifactToUpdate.setListHeatParameters(heatParametersUpdated);
 
-		ArtifactData artifactData = new ArtifactData(artifactWithHeat);
-		Either<ArtifactData, TitanOperationStatus> artifactAfterDelete = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
-		assertTrue(artifactAfterDelete.isRight());
+        Either<ArtifactDefinition, StorageOperationStatus> updateArifact = artifactOperation.updateArifactOnResource(atifactToUpdate, RESOURCE_ID_2, atifactToUpdate.getUniqueId(), NodeTypeEnum.Resource, false);
+        assertTrue(updateArifact.isLeft());
 
-		Either<HeatParameterData, TitanOperationStatus> parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNodeAfterDelete.isRight());
+        // verify old artifact and parameter still exist
+        ArtifactData artifactData = new ArtifactData(artifactWithHeat);
+        Either<ArtifactData, TitanOperationStatus> origArtifact = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
+        assertTrue(origArtifact.isLeft());
+        ArtifactData origArtifactData = origArtifact.left().value();
+        assertEquals(artifactWithHeat.getArtifactVersion(), origArtifactData.getArtifactDataDefinition()
+                                                                            .getArtifactVersion());
 
-		titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class);
-	}
+        Either<HeatParameterData, TitanOperationStatus> parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNodeAfterDelete.isLeft());
 
-	@Test
-	public void testUpdateArtifactWithHeatParams() {
+        // verify new artifact and new parameter
+        ArtifactDefinition artifactDefinitionUpdated = updateArifact.left().value();
+        ArtifactData artifactDataUpdated = new ArtifactData(artifactDefinitionUpdated);
+        Either<ArtifactData, TitanOperationStatus> updatedArtifact = titanDao.getNode(artifactDataUpdated.getUniqueIdKey(), artifactDataUpdated.getUniqueId(), ArtifactData.class);
+        assertTrue(updatedArtifact.isLeft());
+        ArtifactData updatedArtifactData = updatedArtifact.left().value();
+        assertEquals(atifactToUpdate.getArtifactVersion(), updatedArtifactData.getArtifactDataDefinition()
+                                                                              .getArtifactVersion());
+        assertFalse(((String) updatedArtifactData.getUniqueId()).equalsIgnoreCase((String) origArtifactData.getUniqueId()));
 
-		ArtifactDefinition artifactWithHeat = createResourceWithHeat();
+        List<HeatParameterDefinition> heatParametersAfterUpdate = artifactDefinitionUpdated.getListHeatParameters();
+        assertNotNull(heatParametersAfterUpdate);
+        assertEquals(1, heatParametersAfterUpdate.size());
+        HeatParameterDefinition UpdatedHeatParameter = heatParametersAfterUpdate.get(0);
+        assertFalse(UpdatedHeatParameter.getUniqueId().equalsIgnoreCase((String) parameterData.getUniqueId()));
+        Either<HeatParameterData, TitanOperationStatus> parameterNodeAfterUpdate = titanDao.getNode(new HeatParameterData(UpdatedHeatParameter).getUniqueIdKey(), UpdatedHeatParameter.getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNodeAfterUpdate.isLeft());
 
-		List<HeatParameterDefinition> heatParameters = artifactWithHeat.getListHeatParameters();
-		assertNotNull(heatParameters);
-		assertTrue(heatParameters.size() == 1);
-		HeatParameterDefinition parameter = heatParameters.get(0);
-		HeatParameterData parameterData = new HeatParameterData(parameter);
-		Either<HeatParameterData, TitanOperationStatus> parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNode.isLeft());
+        // delete new artifact
+        Either<ArtifactDefinition, StorageOperationStatus> removeArifact = artifactOperation.removeArifactFromResource(RESOURCE_ID_2, artifactDefinitionUpdated.getUniqueId(), NodeTypeEnum.Resource, true, false);
+        assertTrue(removeArifact.isLeft());
 
-		// update to artifact without params
-		ArtifactDefinition artifactNoParams = createArtifactDefinition(USER_ID, RESOURCE_ID, ARTIFACT_NAME);
-		artifactNoParams.setUniqueId(artifactWithHeat.getUniqueId());
-		artifactNoParams.setArtifactType("HEAT");
-		artifactNoParams.setArtifactVersion("2");
-		artifactNoParams.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
+        // verify old artifact and parameter still exist
+        origArtifact = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
+        assertTrue(origArtifact.isLeft());
+        origArtifactData = origArtifact.left().value();
+        assertEquals(artifactWithHeat.getArtifactVersion(), origArtifactData.getArtifactDataDefinition()
+                                                                            .getArtifactVersion());
 
-		Either<ArtifactDefinition, StorageOperationStatus> updateArifact = artifactOperation.updateArifactOnResource(artifactNoParams, RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, false);
-		assertTrue(updateArifact.isLeft());
+        parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNodeAfterDelete.isLeft());
 
-		ArtifactData artifactData = new ArtifactData(artifactWithHeat);
-		Either<ArtifactData, TitanOperationStatus> artifactAfterUpdate = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
-		assertTrue(artifactAfterUpdate.isLeft());
-		ArtifactData artifactAfterUpdateValue = artifactAfterUpdate.left().value();
-		assertTrue(artifactNoParams.getArtifactVersion().equals(artifactAfterUpdateValue.getArtifactDataDefinition().getArtifactVersion()));
+        // verify new artifact is deleted
+        Either<ArtifactData, TitanOperationStatus> artifactAfterDelete = titanDao.getNode(artifactDataUpdated.getUniqueIdKey(), artifactDataUpdated.getUniqueId(), ArtifactData.class);
+        assertTrue(artifactAfterDelete.isRight());
 
-		Either<HeatParameterData, TitanOperationStatus> parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNodeAfterDelete.isRight());
+        parameterNodeAfterDelete = titanDao.getNode(new HeatParameterData(UpdatedHeatParameter).getUniqueIdKey(), new HeatParameterData(UpdatedHeatParameter).getUniqueId(), HeatParameterData.class);
+        assertTrue(parameterNodeAfterDelete.isRight());
 
-		artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, true, false);
-		titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class);
-		titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID_2), ResourceMetadataData.class);
-	}
+        artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, true, false);
+        titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class);
+        titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID_2), ResourceMetadataData.class);
+    }
 
-	@Test
-	public void testUpdateArtifactMetadataWithHeatParams() {
-
-		ArtifactDefinition artifactWithHeat = createResourceWithHeat();
-
-		List<HeatParameterDefinition> heatParameters = artifactWithHeat.getListHeatParameters();
-		assertNotNull(heatParameters);
-		assertTrue(heatParameters.size() == 1);
-		HeatParameterDefinition parameter = heatParameters.get(0);
-		HeatParameterData parameterData = new HeatParameterData(parameter);
-		Either<HeatParameterData, TitanOperationStatus> parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNode.isLeft());
-
-		// update to artifact without params
-		artifactWithHeat.setArtifactVersion("2");
-		artifactWithHeat.setArtifactChecksum(null);
-		artifactWithHeat.setPayloadData(null);
-
-		Either<ArtifactDefinition, StorageOperationStatus> updateArifact = artifactOperation.updateArifactOnResource(artifactWithHeat, RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, false);
-		assertTrue(updateArifact.isLeft());
-
-		ArtifactData artifactData = new ArtifactData(artifactWithHeat);
-		Either<ArtifactData, TitanOperationStatus> artifactAfterUpdate = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
-		assertTrue(artifactAfterUpdate.isLeft());
-		ArtifactData artifactAfterUpdateValue = artifactAfterUpdate.left().value();
-		assertTrue(artifactWithHeat.getArtifactVersion().equals(artifactAfterUpdateValue.getArtifactDataDefinition().getArtifactVersion()));
-
-		Either<HeatParameterData, TitanOperationStatus> parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNodeAfterDelete.isLeft());
-
-		Either<ArtifactDefinition, StorageOperationStatus> removeArifact = artifactOperation.removeArifactFromResource(RESOURCE_ID_2, (String) artifactAfterUpdateValue.getUniqueId(), NodeTypeEnum.Resource, true, false);
-		removeArifact = artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, true, false);
-		titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class);
-		titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID_2), ResourceMetadataData.class);
-
-	}
-
-	@Test
-	public void updateHeatArtifactWithTwoResources() {
-		ArtifactDefinition artifactWithHeat = createResourceWithHeat();
-
-		ResourceMetadataData resource2 = createResource(RESOURCE_ID_2);
-		Map<String, Object> props = new HashMap<String, Object>();
-		props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), ArtifactGroupTypeEnum.DEPLOYMENT.name());
-		Either<GraphRelation, TitanOperationStatus> createRelation = titanDao.createRelation(resource2, new ArtifactData(artifactWithHeat), GraphEdgeLabels.ARTIFACT_REF, props);
-		assertTrue(createRelation.isLeft());
-
-		List<HeatParameterDefinition> heatParameters = artifactWithHeat.getListHeatParameters();
-		assertNotNull(heatParameters);
-		assertTrue(heatParameters.size() == 1);
-		HeatParameterDefinition parameter = heatParameters.get(0);
-		HeatParameterData parameterData = new HeatParameterData(parameter);
-		Either<HeatParameterData, TitanOperationStatus> parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNode.isLeft());
-
-		ArtifactDefinition atifactToUpdate = new ArtifactDefinition(artifactWithHeat);
-
-		// update to artifact without params
-		atifactToUpdate.setArtifactVersion("2");
-		atifactToUpdate.setArtifactChecksum(null);
-		atifactToUpdate.setPayloadData(null);
-
-		HeatParameterDefinition heatParamUpdate = new HeatParameterDefinition(parameter);
-		List<HeatParameterDefinition> heatParametersUpdated = new ArrayList<HeatParameterDefinition>();
-		heatParamUpdate.setCurrentValue("55");
-		heatParametersUpdated.add(heatParamUpdate);
-		atifactToUpdate.setListHeatParameters(heatParametersUpdated);
-
-		Either<ArtifactDefinition, StorageOperationStatus> updateArifact = artifactOperation.updateArifactOnResource(atifactToUpdate, RESOURCE_ID_2, atifactToUpdate.getUniqueId(), NodeTypeEnum.Resource, false);
-		assertTrue(updateArifact.isLeft());
-
-		// verify old artifact and parameter still exist
-		ArtifactData artifactData = new ArtifactData(artifactWithHeat);
-		Either<ArtifactData, TitanOperationStatus> origArtifact = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
-		assertTrue(origArtifact.isLeft());
-		ArtifactData origArtifactData = origArtifact.left().value();
-		assertTrue(artifactWithHeat.getArtifactVersion().equals(origArtifactData.getArtifactDataDefinition().getArtifactVersion()));
-
-		Either<HeatParameterData, TitanOperationStatus> parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNodeAfterDelete.isLeft());
-
-		// verify new artifact and new parameter
-		ArtifactDefinition artifactDefinitionUpdated = updateArifact.left().value();
-		ArtifactData artifactDataUpdated = new ArtifactData(artifactDefinitionUpdated);
-		Either<ArtifactData, TitanOperationStatus> updatedArtifact = titanDao.getNode(artifactDataUpdated.getUniqueIdKey(), artifactDataUpdated.getUniqueId(), ArtifactData.class);
-		assertTrue(updatedArtifact.isLeft());
-		ArtifactData updatedArtifactData = updatedArtifact.left().value();
-		assertTrue(atifactToUpdate.getArtifactVersion().equals(updatedArtifactData.getArtifactDataDefinition().getArtifactVersion()));
-		assertFalse(((String) updatedArtifactData.getUniqueId()).equalsIgnoreCase((String) origArtifactData.getUniqueId()));
-
-		List<HeatParameterDefinition> heatParametersAfterUpdate = artifactDefinitionUpdated.getListHeatParameters();
-		assertNotNull(heatParametersAfterUpdate);
-		assertTrue(heatParametersAfterUpdate.size() == 1);
-		HeatParameterDefinition UpdatedHeatParameter = heatParametersAfterUpdate.get(0);
-		assertFalse(UpdatedHeatParameter.getUniqueId().equalsIgnoreCase((String) parameterData.getUniqueId()));
-		Either<HeatParameterData, TitanOperationStatus> parameterNodeAfterUpdate = titanDao.getNode(new HeatParameterData(UpdatedHeatParameter).getUniqueIdKey(), UpdatedHeatParameter.getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNodeAfterUpdate.isLeft());
-
-		// delete new artifact
-		Either<ArtifactDefinition, StorageOperationStatus> removeArifact = artifactOperation.removeArifactFromResource(RESOURCE_ID_2, artifactDefinitionUpdated.getUniqueId(), NodeTypeEnum.Resource, true, false);
-		assertTrue(removeArifact.isLeft());
-
-		// verify old artifact and parameter still exist
-		origArtifact = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class);
-		assertTrue(origArtifact.isLeft());
-		origArtifactData = origArtifact.left().value();
-		assertTrue(artifactWithHeat.getArtifactVersion().equals(origArtifactData.getArtifactDataDefinition().getArtifactVersion()));
-
-		parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNodeAfterDelete.isLeft());
-
-		// verify new artifact is deleted
-		Either<ArtifactData, TitanOperationStatus> artifactAfterDelete = titanDao.getNode(artifactDataUpdated.getUniqueIdKey(), artifactDataUpdated.getUniqueId(), ArtifactData.class);
-		assertTrue(artifactAfterDelete.isRight());
-
-		parameterNodeAfterDelete = titanDao.getNode(new HeatParameterData(UpdatedHeatParameter).getUniqueIdKey(), new HeatParameterData(UpdatedHeatParameter).getUniqueId(), HeatParameterData.class);
-		assertTrue(parameterNodeAfterDelete.isRight());
-
-		artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, true, false);
-		titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class);
-		titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID_2), ResourceMetadataData.class);
-	}
-
-	private ArtifactDefinition createResourceWithHeat() {
-		ResourceMetadataData resource = createResource(RESOURCE_ID);
-		ArtifactDefinition artifactDefinition = createArtifactDefinition(USER_ID, RESOURCE_ID, ARTIFACT_NAME);
-		artifactDefinition.setArtifactType("HEAT");
-		artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
+    private ArtifactDefinition createResourceWithHeat() {
+        ResourceMetadataData resource = createResource(RESOURCE_ID);
+        ArtifactDefinition artifactDefinition = createArtifactDefinition(USER_ID, RESOURCE_ID, ARTIFACT_NAME);
+        artifactDefinition.setArtifactType("HEAT");
+        artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
 
-		List<HeatParameterDefinition> heatParams = new ArrayList<HeatParameterDefinition>();
-		HeatParameterDefinition heatParam = new HeatParameterDefinition();
-		heatParam.setCurrentValue("11");
-		heatParam.setDefaultValue("22");
-		heatParam.setDescription("desc");
-		heatParam.setName("myParam");
-		heatParam.setType("number");
-		heatParams.add(heatParam);
-		artifactDefinition.setListHeatParameters(heatParams);
+        List<HeatParameterDefinition> heatParams = new ArrayList<>();
+        HeatParameterDefinition heatParam = new HeatParameterDefinition();
+        heatParam.setCurrentValue("11");
+        heatParam.setDefaultValue("22");
+        heatParam.setDescription("desc");
+        heatParam.setName("myParam");
+        heatParam.setType("number");
+        heatParams.add(heatParam);
+        artifactDefinition.setListHeatParameters(heatParams);
 
-		Either<ArtifactDefinition, StorageOperationStatus> artifact = artifactOperation.addArifactToComponent(artifactDefinition, RESOURCE_ID, NodeTypeEnum.Resource, true, false);
-		assertTrue(artifact.isLeft());
-		ArtifactDefinition artifactWithHeat = artifact.left().value();
-		return artifactWithHeat;
-	}
+        Either<ArtifactDefinition, StorageOperationStatus> artifact = artifactOperation.addArifactToComponent(artifactDefinition, RESOURCE_ID, NodeTypeEnum.Resource, true, false);
+        assertTrue(artifact.isLeft());
+        return artifact.left().value();
+    }
 
-	private ArtifactDefinition addArtifactToService(String userId, String serviceId, String artifactName) {
-		ArtifactDefinition artifactInfo = createArtifactDefinition(userId, serviceId, artifactName);
+    private ArtifactDefinition addArtifactToService(String userId, String serviceId, String artifactName) {
+        ArtifactDefinition artifactInfo = createArtifactDefinition(userId, serviceId, artifactName);
 
-		Either<ArtifactDefinition, StorageOperationStatus> artifact = artifactOperation.addArifactToComponent(artifactInfo, serviceId, NodeTypeEnum.Service, true, true);
-		assertTrue(artifact.isLeft());
-		return artifact.left().value();
-	}
+        Either<ArtifactDefinition, StorageOperationStatus> artifact = artifactOperation.addArifactToComponent(artifactInfo, serviceId, NodeTypeEnum.Service, true, true);
+        assertTrue(artifact.isLeft());
+        return artifact.left().value();
+    }
 
-	private ArtifactDefinition createArtifactDefinition(String userId, String serviceId, String artifactName) {
-		ArtifactDefinition artifactInfo = new ArtifactDefinition();
+    private ArtifactDefinition createArtifactDefinition(String userId, String serviceId, String artifactName) {
+        ArtifactDefinition artifactInfo = new ArtifactDefinition();
 
-		artifactInfo.setArtifactName(artifactName + ".sh");
-		artifactInfo.setArtifactType("SHELL");
-		artifactInfo.setDescription("hdkfhskdfgh");
-		artifactInfo.setArtifactChecksum("UEsDBAoAAAAIAAeLb0bDQz");
+        artifactInfo.setArtifactName(artifactName + ".sh");
+        artifactInfo.setArtifactType("SHELL");
+        artifactInfo.setDescription("hdkfhskdfgh");
+        artifactInfo.setArtifactChecksum("UEsDBAoAAAAIAAeLb0bDQz");
 
-		artifactInfo.setUserIdCreator(userId);
-		String fullName = "Jim H";
-		artifactInfo.setUpdaterFullName(fullName);
-		long time = System.currentTimeMillis();
-		artifactInfo.setCreatorFullName(fullName);
-		artifactInfo.setCreationDate(time);
-		artifactInfo.setLastUpdateDate(time);
-		artifactInfo.setUserIdLastUpdater(userId);
-		artifactInfo.setArtifactLabel(artifactName);
-		artifactInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(serviceId, artifactInfo.getArtifactLabel()));
-		return artifactInfo;
-	}
+        artifactInfo.setUserIdCreator(userId);
+        String fullName = "Jim H";
+        artifactInfo.setUpdaterFullName(fullName);
+        long time = System.currentTimeMillis();
+        artifactInfo.setCreatorFullName(fullName);
+        artifactInfo.setCreationDate(time);
+        artifactInfo.setLastUpdateDate(time);
+        artifactInfo.setUserIdLastUpdater(userId);
+        artifactInfo.setArtifactLabel(artifactName);
+        artifactInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(serviceId, artifactInfo.getArtifactLabel()));
+        return artifactInfo;
+    }
 
-	public Service createService(String userId, CategoryDefinition category, String serviceName, String serviceVersion, boolean isHighestVersion) {
+    public Service createService(String userId, CategoryDefinition category, String serviceName, String serviceVersion, boolean isHighestVersion) {
 
-		Service service = buildServiceMetadata(userId, category, serviceName, serviceVersion);
+        Service service = buildServiceMetadata(userId, category, serviceName, serviceVersion);
 
-		service.setHighestVersion(isHighestVersion);
+        service.setHighestVersion(isHighestVersion);
 
-		Either<Service, StorageOperationStatus> result = toscaOperationFacade.createToscaComponent(service);
+        Either<Service, StorageOperationStatus> result = toscaOperationFacade.createToscaComponent(service);
 
-		log.info(result.toString());
-		assertTrue(result.isLeft());
-		Service resultService = result.left().value();
+        log.info(result.toString());
+        assertTrue(result.isLeft());
+        Service resultService = result.left().value();
 
-		assertEquals("check resource state", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, resultService.getLifecycleState());
+        assertEquals("check resource state", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, resultService.getLifecycleState());
 
-		return resultService;
-	}
+        return resultService;
+    }
 
-	private Service buildServiceMetadata(String userId, CategoryDefinition category, String serviceName, String serviceVersion) {
+    private Service buildServiceMetadata(String userId, CategoryDefinition category, String serviceName, String serviceVersion) {
 
-		Service service = new Service();
-		service.setName(serviceName);
-		service.setVersion(serviceVersion);
-		service.setDescription("description 1");
+        Service service = new Service();
+        service.setName(serviceName);
+        service.setVersion(serviceVersion);
+        service.setDescription("description 1");
 
-		service.setCreatorUserId(userId);
-		service.setContactId("contactId@sdc.com");
-		List<CategoryDefinition> categories = new ArrayList<>();
-		categories.add(category);
-		service.setCategories(categories);
-		service.setIcon("images/my.png");
-		List<String> tags = new ArrayList<String>();
-		tags.add("TAG1");
-		tags.add("TAG2");
-		service.setTags(tags);
-		return service;
-	}
+        service.setCreatorUserId(userId);
+        service.setContactId("contactId@sdc.com");
+        List<CategoryDefinition> categories = new ArrayList<>();
+        categories.add(category);
+        service.setCategories(categories);
+        service.setIcon("images/my.png");
+        List<String> tags = new ArrayList<>();
+        tags.add("TAG1");
+        tags.add("TAG2");
+        service.setTags(tags);
+        return service;
+    }
 
-	private void deleteAndCreateCategory(String category) {
-		String[] names = category.split("/");
-		OperationTestsUtil.deleteAndCreateServiceCategory(category, titanDao);
-		OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao);
-	}
+    private void deleteAndCreateCategory(String category) {
+        String[] names = category.split("/");
+        OperationTestsUtil.deleteAndCreateServiceCategory(category, titanDao);
+        OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao);
+    }
 
-	private UserData deleteAndCreateUser(String userId, String firstName, String lastName, String role) {
-		UserData userData = new UserData();
-		userData.setUserId(userId);
-		userData.setFirstName(firstName);
-		userData.setLastName(lastName);
-		if (role != null && !role.isEmpty()) {
-			userData.setRole(role);
-		} else {
-			userData.setRole("ADMIN");
-		}
+    private UserData deleteAndCreateUser(String userId, String firstName, String lastName, String role) {
+        UserData userData = new UserData();
+        userData.setUserId(userId);
+        userData.setFirstName(firstName);
+        userData.setLastName(lastName);
+        if (role != null && !role.isEmpty()) {
+            userData.setRole(role);
+        } else {
+            userData.setRole("ADMIN");
+        }
 
-		titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class);
-		titanDao.createNode(userData, UserData.class);
-		titanDao.commit();
+        titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class);
+        titanDao.createNode(userData, UserData.class);
+        titanDao.commit();
 
-		return userData;
-	}
+        return userData;
+    }
 
-	public ResourceMetadataData createResource(String resourceName) {
+    public ResourceMetadataData createResource(String resourceName) {
 
-		ResourceMetadataData serviceData1 = new ResourceMetadataData();
-		serviceData1.getMetadataDataDefinition().setUniqueId(resourceName);
-		Either<ResourceMetadataData, TitanOperationStatus> createNode = titanDao.createNode(serviceData1, ResourceMetadataData.class);
+        ResourceMetadataData serviceData1 = new ResourceMetadataData();
+        serviceData1.getMetadataDataDefinition().setUniqueId(resourceName);
+        Either<ResourceMetadataData, TitanOperationStatus> createNode = titanDao.createNode(serviceData1, ResourceMetadataData.class);
 
-		assertTrue("check resource created", createNode.isLeft());
-		return createNode.left().value();
-	}
+        assertTrue("check resource created", createNode.isLeft());
+        return createNode.left().value();
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperationTest.java
index 79af87b..79c2d9b 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperationTest.java
@@ -20,12 +20,19 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
 import fj.data.Either;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
+import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
 import org.openecomp.sdc.be.model.ModelTestBase;
 import org.openecomp.sdc.be.model.PropertyConstraint;
@@ -35,246 +42,465 @@
 import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint;
 import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint;
 import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint;
+import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.Map.Entry;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.*;
 import static org.junit.Assert.assertTrue;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:application-context-test.xml")
 public class CapabilityTypeOperationTest extends ModelTestBase {
 
-	@Resource(name = "titan-generic-dao")
-	private TitanGenericDao titanDao;
+    @Resource(name = "titan-generic-dao")
+    private TitanGenericDao titanDao;
 
-	@Resource(name = "capability-type-operation")
-	private CapabilityTypeOperation capabilityTypeOperation;
+    @Resource(name = "capability-type-operation")
+    private CapabilityTypeOperation capabilityTypeOperation;
 
-	@BeforeClass
-	public static void setupBeforeClass() {
-		ModelTestBase.init();
+    @BeforeClass
+    public static void setupBeforeClass() {
+        ModelTestBase.init();
+    }
+    
+    @Before
+    public void cleanUp() {
+        TitanGenericDao titanGenericDao = capabilityTypeOperation.titanGenericDao;
+        Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph();
+        TitanGraph graph = graphResult.left().value();
 
-	}
+        Iterable<TitanVertex> vertices = graph.query().vertices();
+        if (vertices != null) {
+            Iterator<TitanVertex> iterator = vertices.iterator();
+            while (iterator.hasNext()) {
+                TitanVertex vertex = iterator.next();
+                vertex.remove();
+            }
 
-	@Test
-	public void testDummy() {
+        }
+        titanGenericDao.commit();
+    }
 
-		assertTrue(capabilityTypeOperation != null);
+    @Test
+    public void testDummy() {
+        assertNotNull(capabilityTypeOperation);
+    }
 
-	}
+    @Test
+    public void testAddCapabilityType() {
 
-	@Test
-	public void testAddCapabilityType() {
+        CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition();
+        capabilityTypeDefinition.setDescription("desc1");
+        capabilityTypeDefinition.setType("tosca.capabilities.Container1");
 
-		CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition();
-		capabilityTypeDefinition.setDescription("desc1");
-		capabilityTypeDefinition.setType("tosca.capabilities.Container1");
+        Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType1 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
+        assertTrue("check capability type added", addCapabilityType1.isLeft());
 
-		Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType1 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
-		assertEquals("check capability type added", true, addCapabilityType1.isLeft());
+        CapabilityTypeDefinition capabilityTypeAdded = addCapabilityType1.left().value();
+        compareBetweenCreatedToSent(capabilityTypeDefinition, capabilityTypeAdded);
 
-		CapabilityTypeDefinition capabilityTypeAdded = addCapabilityType1.left().value();
-		compareBetweenCreatedToSent(capabilityTypeDefinition, capabilityTypeAdded);
+        Either<CapabilityTypeDefinition, TitanOperationStatus> capabilityTypeByUid = capabilityTypeOperation.getCapabilityTypeByUid(capabilityTypeAdded.getUniqueId());
+        compareBetweenCreatedToSent(capabilityTypeByUid.left().value(), capabilityTypeDefinition);
 
-		Either<CapabilityTypeDefinition, TitanOperationStatus> capabilityTypeByUid = capabilityTypeOperation.getCapabilityTypeByUid(capabilityTypeAdded.getUniqueId());
-		compareBetweenCreatedToSent(capabilityTypeByUid.left().value(), capabilityTypeDefinition);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType2 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
+        assertTrue("check capability type failed", addCapabilityType2.isRight());
+        assertEquals("check returned error", StorageOperationStatus.SCHEMA_VIOLATION, addCapabilityType2.right().value());
 
-		Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType2 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
-		assertEquals("check capability type failed", true, addCapabilityType2.isRight());
-		assertEquals("check returned error", StorageOperationStatus.SCHEMA_VIOLATION, addCapabilityType2.right().value());
+    }
 
-	}
+    @Test
+    public void testAddDerviedCapabilityType() {
 
-	@Test
-	public void testAddDerviedCapabilityType() {
+        CapabilityTypeDefinition capabilityTypeDefinition = createCapabilityTypeDef("tosca.capabilities.Container2", "desc1", "derivedFrom");
 
-		CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition();
-		capabilityTypeDefinition.setDescription("desc1");
-		capabilityTypeDefinition.setType("tosca.capabilities.Container2");
-		capabilityTypeDefinition.setDerivedFrom("derivedFrom");
+        Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType1 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
+        assertEquals("check capability type parent not exist", StorageOperationStatus.NOT_FOUND, addCapabilityType1.right().value());
+    }
 
-		Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType1 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
-		assertEquals("check capability type parent not exist", StorageOperationStatus.INVALID_ID, addCapabilityType1.right().value());
-	}
+    public CapabilityTypeDefinition createCapability(String capabilityTypeName) {
 
-	public CapabilityTypeDefinition createCapability(String capabilityTypeName) {
+        CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition();
+        capabilityTypeDefinition.setDescription("desc1");
+        capabilityTypeDefinition.setType(capabilityTypeName);
 
-		CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition();
-		capabilityTypeDefinition.setDescription("desc1");
-		capabilityTypeDefinition.setType(capabilityTypeName);
+        Map<String, PropertyDefinition> properties = new HashMap<>();
 
-		Map<String, PropertyDefinition> properties = new HashMap<String, PropertyDefinition>();
+        String propName1 = "disk_size";
+        String propName2 = "num_cpus";
 
-		String propName1 = "disk_size";
-		String propName2 = "num_cpus";
+        PropertyDefinition property1 = buildProperty1();
 
-		PropertyDefinition property1 = buildProperty1();
+        properties.put(propName1, property1);
 
-		properties.put(propName1, property1);
+        PropertyDefinition property2 = buildProperty2();
 
-		PropertyDefinition property2 = buildProperty2();
+        properties.put(propName2, property2);
 
-		properties.put(propName2, property2);
+        capabilityTypeDefinition.setProperties(properties);
 
-		capabilityTypeDefinition.setProperties(properties);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType1 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
 
-		Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType1 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
+        CapabilityTypeDefinition capabilityTypeDefinitionCreated = addCapabilityType1.left().value();
+        Either<CapabilityTypeDefinition, StorageOperationStatus> capabilityType = capabilityTypeOperation.getCapabilityType(capabilityTypeDefinitionCreated.getUniqueId(), true);
+        assertTrue("check capability type fetched", capabilityType.isLeft());
+        CapabilityTypeDefinition fetchedCTD = capabilityType.left().value();
 
-		CapabilityTypeDefinition capabilityTypeDefinitionCreated = addCapabilityType1.left().value();
-		Either<CapabilityTypeDefinition, StorageOperationStatus> capabilityType = capabilityTypeOperation.getCapabilityType(capabilityTypeDefinitionCreated.getUniqueId(), true);
-		assertEquals("check capability type fetched", true, capabilityType.isLeft());
-		CapabilityTypeDefinition fetchedCTD = capabilityType.left().value();
+        Map<String, PropertyDefinition> fetchedProps = fetchedCTD.getProperties();
 
-		Map<String, PropertyDefinition> fetchedProps = fetchedCTD.getProperties();
+        compareProperties(fetchedProps, properties);
 
-		compareProperties(fetchedProps, properties);
+        return fetchedCTD;
 
-		return fetchedCTD;
+    }
 
-	}
+    @Test
+    public void testAddCapabilityTypeWithProperties() {
 
-	@Test
-	public void testAddCapabilityTypeWithProperties() {
+        CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition();
+        capabilityTypeDefinition.setDescription("desc1");
+        capabilityTypeDefinition.setType("tosca.capabilities.Container3");
 
-		CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition();
-		capabilityTypeDefinition.setDescription("desc1");
-		capabilityTypeDefinition.setType("tosca.capabilities.Container3");
+        Map<String, PropertyDefinition> properties = new HashMap<>();
 
-		Map<String, PropertyDefinition> properties = new HashMap<String, PropertyDefinition>();
+        String propName1 = "disk_size";
+        String propName2 = "num_cpus";
+
+        PropertyDefinition property1 = buildProperty1();
+
+        properties.put(propName1, property1);
+
+        PropertyDefinition property2 = buildProperty2();
+
+        properties.put(propName2, property2);
+
+        capabilityTypeDefinition.setProperties(properties);
+
+        Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType1 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
+
+        CapabilityTypeDefinition capabilityTypeDefinitionCreated = addCapabilityType1.left().value();
+        Either<CapabilityTypeDefinition, StorageOperationStatus> capabilityType = capabilityTypeOperation.getCapabilityType(capabilityTypeDefinitionCreated.getUniqueId());
+        assertTrue("check capability type fetched", capabilityType.isLeft());
+        CapabilityTypeDefinition fetchedCTD = capabilityType.left().value();
+
+        Map<String, PropertyDefinition> fetchedProps = fetchedCTD.getProperties();
+
+        compareProperties(fetchedProps, properties);
+    }
+
+    private void compareProperties(Map<String, PropertyDefinition> first, Map<String, PropertyDefinition> second) {
+
+        assertTrue("check properties are full or empty", ((first == null && second == null) || (first != null && second != null)));
+        if (first != null) {
+            assertEquals("check properties size", first.size(), second.size());
+
+            for (Entry<String, PropertyDefinition> entry : first.entrySet()) {
+
+                String propName = entry.getKey();
+                PropertyDefinition secondPD = second.get(propName);
+                assertNotNull("Cannot find property " + propName + " in " + second, secondPD);
+
+                PropertyDefinition firstPD = entry.getValue();
+
+                comparePropertyDefinition(firstPD, secondPD);
+            }
+
+        }
+
+    }
+
+    @Test
+    public void testGetCapabilityTypeNotFound() {
+
+        Either<CapabilityTypeDefinition, StorageOperationStatus> capabilityType = capabilityTypeOperation.getCapabilityType("not_exists");
+        assertEquals("check not found is returned", StorageOperationStatus.NOT_FOUND, capabilityType.right().value());
+
+    }
+    
+    
+    
+    @Test
+    public void updateCapabilityType_returnNotFoundErrorIfTryingToUpdateANonExistingType() {
+        CapabilityTypeDefinition currType = createCapabilityTypeDef();
+        CapabilityTypeDefinition updatedType = createCapabilityTypeDef();
+        Either<CapabilityTypeDefinition, StorageOperationStatus> updateCapabilityTypeRes = capabilityTypeOperation.updateCapabilityType(updatedType, currType);
+        assertThat(updateCapabilityTypeRes.right().value()).isEqualTo(StorageOperationStatus.NOT_FOUND);
+    }
+
+    @Test
+    public void updateCapabilityType_basicFields() {
+        CapabilityTypeDefinition createdType = createCapabilityTypeDef("type1", "description1");
+        Either<CapabilityTypeDefinition, StorageOperationStatus> currCapabilityType = capabilityTypeOperation.addCapabilityType(createdType);
+
+        CapabilityTypeDefinition updatedType = createCapabilityTypeDef("type1", "description2");
+        capabilityTypeOperation.updateCapabilityType(updatedType, currCapabilityType.left().value());
+
+        Either<CapabilityTypeDefinition, StorageOperationStatus> fetchedUpdatedType = capabilityTypeOperation.getCapabilityType(createdType.getType());
+        CapabilityTypeDefinition fetchedCapabilityType = fetchedUpdatedType.left().value();
+        assertThat(fetchedCapabilityType.getProperties()).isNullOrEmpty();
+        assertThat(fetchedCapabilityType.getDerivedFrom()).isNullOrEmpty();
+        assertEquals(fetchedCapabilityType.getCreationTime(), updatedType.getCreationTime());
+        assertEquals(fetchedCapabilityType.getType(), updatedType.getType());
+        assertEquals(fetchedCapabilityType.getDescription(), updatedType.getDescription());
+        assertEquals(fetchedCapabilityType.getValidSourceTypes(), updatedType.getValidSourceTypes());
+        assertEquals(fetchedCapabilityType.getVersion(), updatedType.getVersion());
+    }
+
+    @Test
+    public void updateCapabilityType_updatePropertiesFailedDueTypeChange() {
+        PropertyDefinition prop1 = createSimpleProperty("val1", "prop1", "string");
+        CapabilityTypeDefinition capabilityType = createCapabilityTypeDef(asMap(prop1));
+        Either<CapabilityTypeDefinition, StorageOperationStatus> currCapabilityType = capabilityTypeOperation.addCapabilityType(capabilityType);
+
+        PropertyDefinition updatedProp1 = duplicateProperty(prop1, "newVal1", "int");
+        PropertyDefinition prop3 = createSimpleProperty("val3", "prop3", "string");
+        CapabilityTypeDefinition updatedCapabilityType = createCapabilityTypeDef(asMap(updatedProp1, prop3));
+
+        Either<CapabilityTypeDefinition, StorageOperationStatus> updatedCapabilityTypeRes = 
+                capabilityTypeOperation.updateCapabilityType(updatedCapabilityType, currCapabilityType.left().value());
+        
+        assertTrue(updatedCapabilityTypeRes.isRight());
+        assertEquals(StorageOperationStatus.MATCH_NOT_FOUND, updatedCapabilityTypeRes.right().value());
+
+        Either<CapabilityTypeDefinition, StorageOperationStatus> fetchedUpdatedType = capabilityTypeOperation.getCapabilityType(capabilityType.getType());
+        assertEquals(fetchedUpdatedType.left().value().getProperties(), asMap(prop1));
+
+    }
+    
+    @Test
+    public void updateCapabilityType_updatePropertiesFailedDueDeletedProp() {
+        PropertyDefinition prop1 = createSimpleProperty("val1", "prop1", "string");
+        CapabilityTypeDefinition capabilityType = createCapabilityTypeDef(asMap(prop1));
+        Either<CapabilityTypeDefinition, StorageOperationStatus> currCapabilityType = capabilityTypeOperation.addCapabilityType(capabilityType);
+
+        PropertyDefinition prop3 = createSimpleProperty("val3", "prop3", "string");
+        CapabilityTypeDefinition updatedCapabilityType = createCapabilityTypeDef(asMap(prop3));
+
+        Either<CapabilityTypeDefinition, StorageOperationStatus> updatedCapabilityTypeRes = 
+                capabilityTypeOperation.updateCapabilityType(updatedCapabilityType, currCapabilityType.left().value());
+        
+        assertTrue(updatedCapabilityTypeRes.isRight());
+        assertEquals(StorageOperationStatus.MATCH_NOT_FOUND, updatedCapabilityTypeRes.right().value());
+
+        Either<CapabilityTypeDefinition, StorageOperationStatus> fetchedUpdatedType = capabilityTypeOperation.getCapabilityType(capabilityType.getType());
+        assertEquals(fetchedUpdatedType.left().value().getProperties(), asMap(prop1));
+
+    }
+    
+    @Test
+    public void updateCapabilityType_updateProperties() {
+        PropertyDefinition prop1 = createSimpleProperty("val1", "prop1", "string");
+        CapabilityTypeDefinition capabilityType = createCapabilityTypeDef(asMap(prop1));
+        Either<CapabilityTypeDefinition, StorageOperationStatus> currCapabilityType = capabilityTypeOperation.addCapabilityType(capabilityType);
 
-		String propName1 = "disk_size";
-		String propName2 = "num_cpus";
+        PropertyDefinition updatedProp1 = duplicateProperty(prop1, "newVal1", "string");
+        PropertyDefinition prop3 = createSimpleProperty("val3", "prop3", "string");
+        CapabilityTypeDefinition updatedCapabilityType = createCapabilityTypeDef(asMap(updatedProp1, prop3));
 
-		PropertyDefinition property1 = buildProperty1();
+        Either<CapabilityTypeDefinition, StorageOperationStatus> updatedCapabilityTypeRes = 
+                capabilityTypeOperation.updateCapabilityType(updatedCapabilityType, currCapabilityType.left().value());
+        assertTrue(updatedCapabilityTypeRes.isLeft());
+       
+        Either<CapabilityTypeDefinition, StorageOperationStatus> fetchedUpdatedType = capabilityTypeOperation.getCapabilityType(capabilityType.getType());
+        assertEquals(fetchedUpdatedType.left().value().getProperties(), asMap(updatedProp1, prop3));
 
-		properties.put(propName1, property1);
+    }
 
-		PropertyDefinition property2 = buildProperty2();
+    @Test
+    public void updateCapabilityType_derivedFrom_whenNoPrevDerivedFrom_updateToNewDerivedFrom() {
+        CapabilityTypeDefinition rootCapabilityType = createCapabilityTypeDef();
+        CapabilityTypeDefinition capabilityType1 = createCapabilityTypeDef("type1", "descr");
+        CapabilityTypeDefinition updatedCapabilityType = createCapabilityTypeDef("type1", "descr", rootCapabilityType.getType());
+        capabilityTypeOperation.addCapabilityType(rootCapabilityType);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> currCapabilityType = capabilityTypeOperation.addCapabilityType(capabilityType1);
+        capabilityTypeOperation.updateCapabilityType(updatedCapabilityType, currCapabilityType.left().value());
 
-		properties.put(propName2, property2);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> latestCapabilityType = capabilityTypeOperation.getCapabilityType(capabilityType1.getType());
+        assertThat(latestCapabilityType.left().value().getDerivedFrom()).isEqualTo(rootCapabilityType.getType());
+        verifyDerivedFromNodeEqualsToRootCapabilityType(rootCapabilityType, latestCapabilityType.left().value().getUniqueId());
+    }
 
-		capabilityTypeDefinition.setProperties(properties);
+    @Test
+    public void updateCapabilityType_derivedFrom_updateToNullDerivedFrom_Failed() {
+        CapabilityTypeDefinition rootCapabilityType = createCapabilityTypeDef();
+        CapabilityTypeDefinition capabilityType1 = createCapabilityTypeDef("type1", "descr", rootCapabilityType.getType());
+        CapabilityTypeDefinition updatedCapabilityType = createCapabilityTypeDef("type1", "descr", null, new HashMap<>());
+        capabilityTypeOperation.addCapabilityType(rootCapabilityType);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> currCapabilityType = capabilityTypeOperation.addCapabilityType(capabilityType1);
 
-		Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType1 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> updateRes = 
+                capabilityTypeOperation.updateCapabilityType(updatedCapabilityType, currCapabilityType.left().value());
+        
+        assertThat(updateRes.right().value()).isEqualTo(StorageOperationStatus.NOT_FOUND);
 
-		CapabilityTypeDefinition capabilityTypeDefinitionCreated = addCapabilityType1.left().value();
-		Either<CapabilityTypeDefinition, StorageOperationStatus> capabilityType = capabilityTypeOperation.getCapabilityType(capabilityTypeDefinitionCreated.getUniqueId());
-		assertEquals("check capability type fetched", true, capabilityType.isLeft());
-		CapabilityTypeDefinition fetchedCTD = capabilityType.left().value();
+        Either<CapabilityTypeDefinition, StorageOperationStatus> latestCapabilityType = capabilityTypeOperation.getCapabilityType(capabilityType1.getType());
+        assertThat(latestCapabilityType.left().value().getDerivedFrom()).isEqualTo(rootCapabilityType.getType());
+    }
 
-		Map<String, PropertyDefinition> fetchedProps = fetchedCTD.getProperties();
+    @Test
+    public void updateCapabilityType_updateDerivedFrom() {
+        CapabilityTypeDefinition rootCapabilityType = createCapabilityTypeDef();
+        CapabilityTypeDefinition derivedType1 = createCapabilityTypeDef("derivedType1", "descr", rootCapabilityType.getType());
+        CapabilityTypeDefinition capabilityType1 = createCapabilityTypeDef("type1", "descr", rootCapabilityType.getType());
+        CapabilityTypeDefinition updatedCapabilityType = createCapabilityTypeDef("type1", "descr", derivedType1.getType());
 
-		compareProperties(fetchedProps, properties);
-	}
+        capabilityTypeOperation.addCapabilityType(rootCapabilityType);
+        capabilityTypeOperation.addCapabilityType(derivedType1);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> currCapabilityType = capabilityTypeOperation.addCapabilityType(capabilityType1);
 
-	private void compareProperties(Map<String, PropertyDefinition> first, Map<String, PropertyDefinition> second) {
+        capabilityTypeOperation.updateCapabilityType(updatedCapabilityType, currCapabilityType.left().value());
 
-		assertTrue("check properties are full or empty", ((first == null && second == null) || (first != null && second != null)));
-		if (first != null) {
-			assertEquals("check properties size", first.size(), second.size());
+        Either<CapabilityTypeDefinition, StorageOperationStatus> latestCapabilityType = capabilityTypeOperation.getCapabilityType(capabilityType1.getType());
+        assertThat(latestCapabilityType.left().value().getDerivedFrom()).isEqualTo(derivedType1.getType());
+        verifyDerivedFromNodeEqualsToRootCapabilityType(derivedType1, latestCapabilityType.left().value().getUniqueId());
+    }
+    
+    @Test
+    public void updateCapabilityType_updateDerivedFrom_Failed_NewParentIsNotChildOfOldOne() {
+        CapabilityTypeDefinition rootCapabilityType = createCapabilityTypeDef();
+        CapabilityTypeDefinition notDerivedType = createCapabilityTypeDef("derivedType1", "descr");
+        CapabilityTypeDefinition capabilityType1 = createCapabilityTypeDef("type1", "descr", rootCapabilityType.getType());
+        CapabilityTypeDefinition updatedCapabilityType = createCapabilityTypeDef("type1", "descr", notDerivedType.getType());
 
-			for (Entry<String, PropertyDefinition> entry : first.entrySet()) {
+        capabilityTypeOperation.addCapabilityType(rootCapabilityType);
+        capabilityTypeOperation.addCapabilityType(notDerivedType);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> currCapabilityType = capabilityTypeOperation.addCapabilityType(capabilityType1);
 
-				String propName = entry.getKey();
-				PropertyDefinition secondPD = second.get(propName);
-				assertNotNull("Cannot find property " + propName + " in " + second, secondPD);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> result = capabilityTypeOperation.updateCapabilityType(updatedCapabilityType, currCapabilityType.left().value());
+        assertThat(result.right().value()).isEqualTo(StorageOperationStatus.CANNOT_UPDATE_EXISTING_ENTITY);
 
-				PropertyDefinition firstPD = entry.getValue();
+        Either<CapabilityTypeDefinition, StorageOperationStatus> latestCapabilityType = capabilityTypeOperation.getCapabilityType(capabilityType1.getType());
+        assertThat(latestCapabilityType.left().value().getDerivedFrom()).isEqualTo(rootCapabilityType.getType());
+        verifyDerivedFromNodeEqualsToRootCapabilityType(rootCapabilityType, latestCapabilityType.left().value().getUniqueId());
+    }
+    
+    private CapabilityTypeDefinition createCapabilityTypeDef() {
+        return createCapabilityTypeDef("tosca.capabilities.Root", "The TOSCA root Capability Type all other TOSCA base Capability Types derived from", null, new HashMap<>());
+    }
 
-				comparePropertyDefinition(firstPD, secondPD);
-			}
+    private CapabilityTypeDefinition createCapabilityTypeDef(Map<String, PropertyDefinition> properties) {
+        return createCapabilityTypeDef("tosca.capabilities.Root",
+                "The TOSCA root Capability Type all other TOSCA base Capability Types derived from", null, properties);
+    }
+    
+    private CapabilityTypeDefinition createCapabilityTypeDef(String type, String description) {
+        return createCapabilityTypeDef(type, description, null, null);
+    }
 
-		}
+    private CapabilityTypeDefinition createCapabilityTypeDef(String type, String description, String derivedFrom) {
+        return createCapabilityTypeDef(type, description, derivedFrom, null);
+    }
 
-	}
+    
+    private CapabilityTypeDefinition createCapabilityTypeDef(String type, String description, String derivedFrom,  Map<String, PropertyDefinition> properties) {
+        CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition();
+        capabilityTypeDefinition.setDescription(description);
+        capabilityTypeDefinition.setType(type);
+        capabilityTypeDefinition.setDerivedFrom(derivedFrom);
+        capabilityTypeDefinition.setVersion("1.0");
+        capabilityTypeDefinition.setValidSourceTypes(null);
+        if (properties != null) {
+            capabilityTypeDefinition.setProperties(properties);
+        }
+        return capabilityTypeDefinition;
+    }
 
-	@Test
-	public void testGetCapabilityTypeNotFound() {
+    private PropertyDefinition duplicateProperty(PropertyDefinition prop1, String updatedValue, String updatedType) {
+        PropertyDefinition updatedProp1 = new PropertyDefinition(prop1);
+        updatedProp1.setDefaultValue(updatedValue);
+        updatedProp1.setType(updatedType);
+        return updatedProp1;
+    }
 
-		Either<CapabilityTypeDefinition, StorageOperationStatus> capabilityType = capabilityTypeOperation.getCapabilityType("not_exists");
-		assertEquals("check not found is returned", StorageOperationStatus.NOT_FOUND, capabilityType.right().value());
+    private static Map<String, PropertyDefinition> asMap(PropertyDefinition ... props) {
+        return Stream.of(props).collect(Collectors.toMap(PropertyDefinition::getName, Function.identity()));
+    }
 
-	}
+    private void verifyDerivedFromNodeEqualsToRootCapabilityType(CapabilityTypeDefinition rootCapabilityType, String parentCapabilityId) {
+        Either<ImmutablePair<CapabilityTypeData, GraphEdge>, TitanOperationStatus> derivedFromRelation = titanDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), parentCapabilityId, GraphEdgeLabels.DERIVED_FROM,
+                NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
+        assertThat(derivedFromRelation.left().value().getLeft().getCapabilityTypeDataDefinition())
+                .isEqualToComparingFieldByField(rootCapabilityType);
+    }
 
-	private void comparePropertyDefinition(PropertyDefinition first, PropertyDefinition second) {
 
-		assertTrue("check objects are full or empty", ((first == null && second == null) || (first != null && second != null)));
-		if (first != null) {
-			assertTrue("check property default value", compareValue(first.getDefaultValue(), second.getDefaultValue()));
-			assertTrue("check property description", compareValue(first.getDescription(), second.getDescription()));
-			assertTrue("check property type", compareValue(first.getType(), second.getType()));
-			compareList(first.getConstraints(), second.getConstraints());
-		}
+    private void comparePropertyDefinition(PropertyDefinition first, PropertyDefinition second) {
 
-	}
+        assertTrue("check objects are full or empty", ((first == null && second == null) || (first != null && second != null)));
+        if (first != null) {
+            assertTrue("check property default value", compareValue(first.getDefaultValue(), second.getDefaultValue()));
+            assertTrue("check property description", compareValue(first.getDescription(), second.getDescription()));
+            assertTrue("check property type", compareValue(first.getType(), second.getType()));
+            compareList(first.getConstraints(), second.getConstraints());
+        }
 
-	private void compareList(List<PropertyConstraint> first, List<PropertyConstraint> second) {
+    }
 
-		assertTrue("check lists are full or empty", ((first == null && second == null) || (first != null && second != null)));
-		if (first != null) {
-			assertEquals("check list size", first.size(), second.size());
-		}
-	}
+    private void compareList(List<PropertyConstraint> first, List<PropertyConstraint> second) {
 
-	private PropertyDefinition buildProperty2() {
-		PropertyDefinition property2 = new PropertyDefinition();
-		property2.setDefaultValue("2");
-		property2.setDescription("Number of (actual or virtual) CPUs associated with the Compute node.");
-		property2.setType(ToscaType.INTEGER.name().toLowerCase());
-		List<PropertyConstraint> constraints3 = new ArrayList<PropertyConstraint>();
-		List<String> range = new ArrayList<String>();
-		range.add("1");
-		range.add("4");
+        assertTrue("check lists are full or empty", ((first == null && second == null) || (first != null && second != null)));
+        if (first != null) {
+            assertEquals("check list size", first.size(), second.size());
+        }
+    }
 
-		InRangeConstraint propertyConstraint3 = new InRangeConstraint(range);
-		constraints3.add(propertyConstraint3);
-		// property2.setConstraints(constraints3);
-		property2.setConstraints(constraints3);
-		return property2;
-	}
+    private PropertyDefinition buildProperty2() {
+        PropertyDefinition property2 = new PropertyDefinition();
+        property2.setDefaultValue("2");
+        property2.setDescription("Number of (actual or virtual) CPUs associated with the Compute node.");
+        property2.setType(ToscaType.INTEGER.name().toLowerCase());
+        List<PropertyConstraint> constraints3 = new ArrayList<>();
+        List<String> range = new ArrayList<>();
+        range.add("1");
+        range.add("4");
 
-	private PropertyDefinition buildProperty1() {
-		PropertyDefinition property1 = new PropertyDefinition();
-		property1.setDefaultValue("10");
-		property1.setDescription("Size of the local disk, in Gigabytes (GB), available to applications running on the Compute node.");
-		property1.setType(ToscaType.INTEGER.name().toLowerCase());
-		List<PropertyConstraint> constraints = new ArrayList<PropertyConstraint>();
-		GreaterThanConstraint propertyConstraint1 = new GreaterThanConstraint("0");
-		constraints.add(propertyConstraint1);
+        InRangeConstraint propertyConstraint3 = new InRangeConstraint(range);
+        constraints3.add(propertyConstraint3);
+        // property2.setConstraints(constraints3);
+        property2.setConstraints(constraints3);
+        return property2;
+    }
 
-		LessOrEqualConstraint propertyConstraint2 = new LessOrEqualConstraint("10");
-		constraints.add(propertyConstraint2);
+    private PropertyDefinition buildProperty1() {
+        PropertyDefinition property1 = new PropertyDefinition();
+        property1.setDefaultValue("10");
+        property1.setDescription("Size of the local disk, in Gigabytes (GB), available to applications running on the Compute node.");
+        property1.setType(ToscaType.INTEGER.name().toLowerCase());
+        List<PropertyConstraint> constraints = new ArrayList<>();
+        GreaterThanConstraint propertyConstraint1 = new GreaterThanConstraint("0");
+        constraints.add(propertyConstraint1);
 
-		property1.setConstraints(constraints);
-		return property1;
-	}
+        LessOrEqualConstraint propertyConstraint2 = new LessOrEqualConstraint("10");
+        constraints.add(propertyConstraint2);
 
-	private void compareBetweenCreatedToSent(CapabilityTypeDefinition x, CapabilityTypeDefinition y) {
+        property1.setConstraints(constraints);
+        return property1;
+    }
 
-		assertTrue(compareValue(x.getDerivedFrom(), y.getDerivedFrom()));
-		assertTrue(compareValue(x.getType(), y.getType()));
-		assertTrue(compareValue(x.getDescription(), y.getDescription()));
+    private void compareBetweenCreatedToSent(CapabilityTypeDefinition x, CapabilityTypeDefinition y) {
+        assertTrue(compareValue(x.getDerivedFrom(), y.getDerivedFrom()));
+        assertTrue(compareValue(x.getType(), y.getType()));
+        assertTrue(compareValue(x.getDescription(), y.getDescription()));
 
-	}
+    }
 
-	public boolean compareValue(String first, String second) {
+    private boolean compareValue(String first, String second) {
 
-		if (first == null && second == null) {
-			return true;
-		}
-		if (first != null) {
-			return first.equals(second);
-		} else {
-			return false;
-		}
-	}
+        if (first == null && second == null) {
+            return true;
+        }
+        if (first != null) {
+            return first.equals(second);
+        } else {
+            return false;
+        }
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationTest.java
index 321bc42..4e97dc5 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationTest.java
@@ -1,12 +1,11 @@
 package org.openecomp.sdc.be.model.operations.impl;
 
+import fj.data.Either;
 import org.junit.Test;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.model.ComponentInstanceInput;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 
-import fj.data.Either;
-
 public class ComponentInstanceOperationTest {
 
 	private ComponentInstanceOperation createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java
index b28641c..9b2a5d9 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java
@@ -20,13 +20,7 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
+import fj.data.Either;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -48,53 +42,58 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import fj.data.Either;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:application-context-test.xml")
 public class ElementOperationTest extends ModelTestBase {
 
-	@javax.annotation.Resource(name = "element-operation")
-	private ElementOperation elementOperation;
+    @javax.annotation.Resource(name = "element-operation")
+    private ElementOperation elementOperation;
 
-	@javax.annotation.Resource(name = "titan-generic-dao")
-	private TitanGenericDao titanDao;
+    @javax.annotation.Resource(name = "titan-generic-dao")
+    private TitanGenericDao titanDao;
 
-	private static String CATEGORY = "category";
-	private static String SUBCATEGORY = "subcategory";
+    private static String CATEGORY = "category";
+    private static String SUBCATEGORY = "subcategory";
 
-	@BeforeClass
-	public static void setupBeforeClass() {
-		// ExternalConfiguration.setAppName("catalog-model");
-		// String appConfigDir = "src/test/resources/config/catalog-model";
-		// ConfigurationSource configurationSource = new
-		// FSConfigurationSource(ExternalConfiguration.getChangeListener(),
-		// appConfigDir);
+    @BeforeClass
+    public static void setupBeforeClass() {
+        // ExternalConfiguration.setAppName("catalog-model");
+        // String appConfigDir = "src/test/resources/config/catalog-model";
+        // ConfigurationSource configurationSource = new
+        // FSConfigurationSource(ExternalConfiguration.getChangeListener(),
+        // appConfigDir);
 
-		ModelTestBase.init();
+        ModelTestBase.init();
 
-	}
+    }
 
-	@Test
-	public void testGetArtifactsTypes() {
+    @Test
+    public void testGetArtifactsTypes() {
 
-		List<String> artifactTypesCfg = new ArrayList<String>();
-		artifactTypesCfg.add("type1");
-		artifactTypesCfg.add("type2");
-		artifactTypesCfg.add("type3");
-		artifactTypesCfg.add("type4");
-		configurationManager.getConfiguration().setArtifactTypes(artifactTypesCfg);
-		Either<List<ArtifactType>, ActionStatus> allArtifactTypes = elementOperation.getAllArtifactTypes();
-		assertTrue(allArtifactTypes.isLeft());
-		assertEquals(artifactTypesCfg.size(), allArtifactTypes.left().value().size());
+        List<String> artifactTypesCfg = new ArrayList<>();
+        artifactTypesCfg.add("type1");
+        artifactTypesCfg.add("type2");
+        artifactTypesCfg.add("type3");
+        artifactTypesCfg.add("type4");
+        configurationManager.getConfiguration().setArtifactTypes(artifactTypesCfg);
+        Either<List<ArtifactType>, ActionStatus> allArtifactTypes = elementOperation.getAllArtifactTypes();
+        assertTrue(allArtifactTypes.isLeft());
+        assertEquals(artifactTypesCfg.size(), allArtifactTypes.left().value().size());
 
-		artifactTypesCfg.remove(0);
-		allArtifactTypes = elementOperation.getAllArtifactTypes();
-		assertTrue(allArtifactTypes.isLeft());
-		assertEquals(artifactTypesCfg.size(), allArtifactTypes.left().value().size());
+        artifactTypesCfg.remove(0);
+        allArtifactTypes = elementOperation.getAllArtifactTypes();
+        assertTrue(allArtifactTypes.isLeft());
+        assertEquals(artifactTypesCfg.size(), allArtifactTypes.left().value().size());
 
-		artifactTypesCfg.add("type5");
-	}
+        artifactTypesCfg.add("type5");
+    }
 
 	@Test
 	public void testAllDeploymentArtifactTypes() {
@@ -111,23 +110,22 @@
 
 	}
 
-	// @Test
-	public void testGetResourceAndServiceCategoty() {
-		String id = OperationTestsUtil.deleteAndCreateResourceCategory(CATEGORY, SUBCATEGORY, titanDao);
+    // @Test
+    public void testGetResourceAndServiceCategoty() {
+        String id = OperationTestsUtil.deleteAndCreateResourceCategory(CATEGORY, SUBCATEGORY, titanDao);
 
-		Either<CategoryDefinition, ActionStatus> res = elementOperation.getCategory(NodeTypeEnum.ResourceNewCategory,
-				id);
-		assertTrue(res.isLeft());
-		CategoryDefinition categoryDefinition = (CategoryDefinition) res.left().value();
-		assertEquals(CATEGORY, categoryDefinition.getName());
-		assertEquals(SUBCATEGORY, categoryDefinition.getSubcategories().get(0).getName());
+        Either<CategoryDefinition, ActionStatus> res = elementOperation.getCategory(NodeTypeEnum.ResourceNewCategory, id);
+        assertTrue(res.isLeft());
+        CategoryDefinition categoryDefinition = (CategoryDefinition) res.left().value();
+        assertEquals(CATEGORY, categoryDefinition.getName());
+        assertEquals(SUBCATEGORY, categoryDefinition.getSubcategories().get(0).getName());
 
-		id = OperationTestsUtil.deleteAndCreateServiceCategory(CATEGORY, titanDao);
+        id = OperationTestsUtil.deleteAndCreateServiceCategory(CATEGORY, titanDao);
 
-		res = elementOperation.getCategory(NodeTypeEnum.ServiceNewCategory, id);
-		assertTrue(res.isLeft());
-		categoryDefinition = (CategoryDefinition) res.left().value();
-		assertEquals(CATEGORY, categoryDefinition.getName());
+        res = elementOperation.getCategory(NodeTypeEnum.ServiceNewCategory, id);
+        assertTrue(res.isLeft());
+        categoryDefinition = (CategoryDefinition) res.left().value();
+        assertEquals(CATEGORY, categoryDefinition.getName());
 	}
 
 	private ElementOperation createTestSubject() {
@@ -496,5 +494,5 @@
 		testSubject = createTestSubject();
 		name = "";
 		result = testSubject.getNewCategoryData(name, type, null);
-	}
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperationTest.java
index 15c5e64..94e22e6 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperationTest.java
@@ -1,32 +1,22 @@
 package org.openecomp.sdc.be.model.operations.impl;
 
-import static com.google.common.collect.Sets.newHashSet;
-import static java.util.Arrays.asList;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Resource;
-
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
+import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.junit.After;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
-import org.openecomp.sdc.be.model.GroupTypeDefinition;
-import org.openecomp.sdc.be.model.ModelTestBase;
-import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.datatypes.elements.GroupTypeDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
@@ -34,12 +24,24 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import fj.data.Either;
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.collect.Sets.newHashSet;
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.*;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:application-context-test.xml")
 public class GroupTypeOperationTest extends ModelTestBase {
+
     private static final String TOSCA_GROUPS_ROOT = "tosca.groups.Root";
+    private static final String NULL_STRING = null;
 
     @Resource(name = "titan-generic-dao")
     private TitanGenericDao titanDao;
@@ -58,6 +60,7 @@
     @After
     public void tearDown() {
         titanDao.rollback();
+        cleanUp();
     }
 
     @Test
@@ -71,7 +74,7 @@
 
         List<GroupTypeDefinition> allGroupTypesNoExclusion = groupTypeOperation.getAllGroupTypes(null);
         assertThat(allGroupTypesNoExclusion)
-                .usingElementComparatorOnFields("type")
+                .usingElementComparatorOnFields("type", "icon", "name")
                 .containsExactlyInAnyOrder(rootGroupDefinition, type1, type2);
     }
 
@@ -91,7 +94,7 @@
     }
 
     @Test
-    public void groupTypeWithoutCapabilityTypeCreated() {
+    public void groupTypeWithoutCapabilityCreated() {
         GroupTypeData rootNode = getOrCreateRootGroupTypeNode();
         
         GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
@@ -108,12 +111,12 @@
         
         groupTypeDefinition.setProperties(properties );
         
-        Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition, false);
-        assertEquals("check group type added", true, addGroupTypeResult.isLeft());
+        Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition, true);
+        assertTrue("check group type added", addGroupTypeResult.isLeft());
         compareBetweenCreatedToSent(groupTypeDefinition, addGroupTypeResult.left().value());
         
         addGroupTypeResult = groupTypeOperation.getGroupTypeByTypeAndVersion("org.openecomp.groups.NetworkCollection", "1.0");
-        assertEquals("check group type added", true, addGroupTypeResult.isLeft());
+        assertTrue("check group type added", addGroupTypeResult.isLeft());
         compareBetweenCreatedToSent(groupTypeDefinition, addGroupTypeResult.left().value());
         
         Either<GroupTypeData, TitanOperationStatus> groupTypeResult = titanDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), groupTypeDefinition.getType(), GroupTypeData.class);
@@ -124,18 +127,64 @@
     }
     
     @Test
+    public void groupTypeWithCapabilityAndPropsButCapTypeWithoutProps() {
+        getOrCreateRootGroupTypeNode();
+
+        CapabilityTypeDefinition capabilityTypeDef = createCapabilityType(null);
+        Either<CapabilityTypeData, TitanOperationStatus> capabilityTypeResult = titanDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), capabilityTypeDef.getType(), CapabilityTypeData.class);
+        extractVal(capabilityTypeResult);
+
+        GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
+        groupTypeDefinition.setDerivedFrom(TOSCA_GROUPS_ROOT);
+        groupTypeDefinition.setDescription("groups l3-networks in network collection");
+        groupTypeDefinition.setType("org.openecomp.groups.NetworkCollection");
+
+        Map<String, CapabilityDefinition> mapCapabilities = new HashMap<>();
+
+        ComponentInstanceProperty property = new ComponentInstanceProperty(
+                buildProperty("vfc_instance_group_reference", null, "Ability to recognize capability per vfc instance group on vnf instance"));
+        CapabilityDefinition capabilityDef = buildCapabilityDefintion(asList(property));
+        mapCapabilities.put("vlan_assignment", capabilityDef);
+        groupTypeDefinition.setCapabilities(mapCapabilities);
+
+
+        List<PropertyDefinition> properties = asList(
+                buildProperty("vfc_instance_group_role", null, "role of this VFC group"),
+                buildProperty("vfc_parent_port_role", null, "common role of parent ports of VFCs in this group"),
+                buildProperty("network_collection_role", null, "network collection role assigned to this group"),
+                buildProperty("subinterface_role", null, "common role of subinterfaces of VFCs in this group, criteria the group is created"));
+
+        groupTypeDefinition.setProperties(properties );
+
+        Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition, true);
+        assertTrue(addGroupTypeResult.isRight());
+        assertEquals(StorageOperationStatus.MATCH_NOT_FOUND, addGroupTypeResult.right().value());
+    }
+
+    @Test
     public void groupTypeWithCapabilityTypeAndEdgeCreated() {
         GroupTypeData rootNode = getOrCreateRootGroupTypeNode();
         
-        CapabilityTypeDefinition capabilityTypeDef = createCapabilityType();
+        Map<String, PropertyDefinition> capTypeProperties = new HashMap<>();
+        capTypeProperties.put("vfc_instance_group_reference",
+                buildProperty("vfc_instance_group_reference", null, "Ability to recognize capability per vfc instance group on vnf instance"));
+
+        CapabilityTypeDefinition capabilityTypeDef = createCapabilityType(capTypeProperties);
         Either<CapabilityTypeData, TitanOperationStatus> capabilityTypeResult = titanDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), capabilityTypeDef.getType(), CapabilityTypeData.class);
-        CapabilityTypeData capabilityTypeNode = extractVal(capabilityTypeResult);
+        extractVal(capabilityTypeResult);
         
         GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
         groupTypeDefinition.setDerivedFrom(TOSCA_GROUPS_ROOT);
         groupTypeDefinition.setDescription("groups l3-networks in network collection");
         groupTypeDefinition.setType("org.openecomp.groups.NetworkCollection");
-        groupTypeDefinition.setCapabilityTypes(asList(capabilityTypeDef));
+
+        Map<String, CapabilityDefinition> mapCapabilities = new HashMap<>();
+        ComponentInstanceProperty property = new ComponentInstanceProperty(
+                buildProperty("vfc_instance_group_reference", null, "Ability to recognize capability per vfc instance group on vnf instance"));
+        CapabilityDefinition capabilityDef = buildCapabilityDefintion(asList(property));
+        mapCapabilities.put("vlan_assignment", capabilityDef);
+        groupTypeDefinition.setCapabilities(mapCapabilities);
+        
         
         List<PropertyDefinition> properties = asList(
                 buildProperty("vfc_instance_group_role", null, "role of this VFC group"),
@@ -146,88 +195,276 @@
         groupTypeDefinition.setProperties(properties );
         
         Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition, true);
-        assertEquals("check group type added", true, addGroupTypeResult.isLeft());
+        assertTrue("check group type added", addGroupTypeResult.isLeft());
         compareBetweenCreatedToSent(groupTypeDefinition, addGroupTypeResult.left().value());
         
         Either<GroupTypeData, TitanOperationStatus> groupTypeResult = titanDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), groupTypeDefinition.getType(), GroupTypeData.class);
         GroupTypeData groupTypeNode = extractVal(groupTypeResult);
         
-        Either<Edge, TitanOperationStatus> edgeCapTypeResult = titanDao.getEdgeByNodes(groupTypeNode, capabilityTypeNode, GraphEdgeLabels.GROUP_TYPE_CAPABILITY_TYPE);
-        validate(edgeCapTypeResult);
+        Either<GroupTypeDefinition, StorageOperationStatus> groupTypeDefResult = groupTypeOperation.getGroupTypeByUid(groupTypeNode.getUniqueId());
+        assertTrue(groupTypeDefResult.isLeft());
+        GroupTypeDefinition groupTypeDefinitionRetrieved = groupTypeDefResult.left().value();
+        assertNotNull(groupTypeDefinitionRetrieved);
+        Map<String, CapabilityDefinition> capabilityDefs = groupTypeDefinitionRetrieved.getCapabilities();
+        assertNotNull(capabilityDefs);
+        assertEquals(1, capabilityDefs.size());
+        assertTrue(capabilityDefs.containsKey("vlan_assignment"));
+        CapabilityDefinition updatedCapabilityDef = capabilityDefs.get("vlan_assignment");
+        assertEquals(2, updatedCapabilityDef.getProperties().size());
         
         Either<Edge, TitanOperationStatus> edgeDerivedFromResult = titanDao.getEdgeByNodes(groupTypeNode, rootNode, GraphEdgeLabels.DERIVED_FROM);
         validate(edgeDerivedFromResult);
     }
     
     @Test
-    public void testUpgradeGroupTypeWithDerrivedFromEdge() {
+    public void groupTypeWithCapabilityTypeAndEdgeCreated_OverrideDefaultCapabilityTypeValue() {
+        getOrCreateRootGroupTypeNode();
+
+        PropertyDefinition property = buildProperty("vfc_instance_group_reference", null, "Ability to recognize capability per vfc instance group on vnf instance");
+
+        Map<String, PropertyDefinition> capTypeProperties = new HashMap<>();
+        capTypeProperties.put("vfc_instance_group_reference", property);
+        CapabilityTypeDefinition capabilityTypeDef = createCapabilityType(capTypeProperties);
+        Either<CapabilityTypeData, TitanOperationStatus> capabilityTypeResult = titanDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), capabilityTypeDef.getType(), CapabilityTypeData.class);
+        extractVal(capabilityTypeResult);
+
         GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
         groupTypeDefinition.setDerivedFrom(TOSCA_GROUPS_ROOT);
+        groupTypeDefinition.setDescription("groups l3-networks in network collection");
+        groupTypeDefinition.setType("org.openecomp.groups.NetworkCollection");
+
+        Map<String, CapabilityDefinition> mapCapabilities = new HashMap<>();
+        property.setValue("new_value");
+        ComponentInstanceProperty capDefProperty = new ComponentInstanceProperty(property);
+        CapabilityDefinition capabilityDef = buildCapabilityDefintion(asList(capDefProperty));
+        mapCapabilities.put("vlan_assignment", capabilityDef);
+        groupTypeDefinition.setCapabilities(mapCapabilities);
+
+
+        List<PropertyDefinition> properties = asList(
+                buildProperty("vfc_instance_group_role", null, "role of this VFC group"),
+                buildProperty("vfc_parent_port_role", null, "common role of parent ports of VFCs in this group"),
+                buildProperty("network_collection_role", null, "network collection role assigned to this group"),
+                buildProperty("subinterface_role", null, "common role of subinterfaces of VFCs in this group, criteria the group is created"));
+
+        groupTypeDefinition.setProperties(properties );
+
+        Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition, true);
+        assertTrue("check group type added", addGroupTypeResult.isLeft());
+        compareBetweenCreatedToSent(groupTypeDefinition, addGroupTypeResult.left().value());
+
+        Either<GroupTypeData, TitanOperationStatus> groupTypeResult = titanDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), groupTypeDefinition.getType(), GroupTypeData.class);
+        GroupTypeData groupTypeNode = extractVal(groupTypeResult);
+
+        Either<GroupTypeDefinition, StorageOperationStatus> groupTypeDefResult = groupTypeOperation.getGroupTypeByUid(groupTypeNode.getUniqueId());
+        assertTrue(groupTypeDefResult.isLeft());
+        GroupTypeDefinition groupTypeDefinitionRetrieved = groupTypeDefResult.left().value();
+        assertNotNull(groupTypeDefinitionRetrieved);
+        Map<String, CapabilityDefinition> capabilityDefs = groupTypeDefinitionRetrieved.getCapabilities();
+        assertNotNull(capabilityDefs);
+        assertEquals(1, capabilityDefs.size());
+        assertTrue(capabilityDefs.containsKey("vlan_assignment"));
+
+        CapabilityDefinition capDefinition = capabilityDefs.get("vlan_assignment");
+        assertEquals("new_value", capDefinition.getProperties().get(0).getValue());
+        assertEquals(2, capDefinition.getProperties().size());
+    }
+    
+    
+    @Test
+    public void updateGroupTypeWithCapability_FailedDueToCapabilityDeleteAttempt() {
+        createRootGroupTypeNode();
+
+        PropertyDefinition property = buildProperty("vfc_instance_group_reference", null, "Ability to recognize capability per vfc instance group on vnf instance");
+
+        Map<String, PropertyDefinition> capTypeProperties = new HashMap<>();
+        capTypeProperties.put("vfc_instance_group_reference", property);
+        CapabilityTypeDefinition capabilityTypeDef = createCapabilityType(capTypeProperties);
+        Either<CapabilityTypeData, TitanOperationStatus> capabilityTypeResult = titanDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), capabilityTypeDef.getType(), CapabilityTypeData.class);
+        extractVal(capabilityTypeResult);
+
+        GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
+        groupTypeDefinition.setDerivedFrom(TOSCA_GROUPS_ROOT);
+        groupTypeDefinition.setDescription("groups l3-networks in network collection");
+        groupTypeDefinition.setType("org.openecomp.groups.NetworkCollection");
+
+        Map<String, CapabilityDefinition> mapCapabilities = new HashMap<>();
+        property.setValue("new_value");
+        ComponentInstanceProperty capDefProperty = new ComponentInstanceProperty(property);
+        CapabilityDefinition capabilityDef = buildCapabilityDefintion(asList(capDefProperty));
+        mapCapabilities.put("vlan_assignment", capabilityDef);
+        groupTypeDefinition.setCapabilities(mapCapabilities);
+
+        Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition);
+        assertTrue(addGroupTypeResult.isLeft());
+        
+        GroupTypeDefinition newGroupTypeDefinition = new GroupTypeDefinition();
+        newGroupTypeDefinition.setDerivedFrom(TOSCA_GROUPS_ROOT);
+        newGroupTypeDefinition.setDescription("groups l3-networks in network collection");
+        newGroupTypeDefinition.setType("org.openecomp.groups.NetworkCollection");
+        Either<GroupTypeDefinition, StorageOperationStatus> updateGroupTypeResult =  groupTypeOperation.updateGroupType(newGroupTypeDefinition, addGroupTypeResult.left().value());
+        assertTrue(updateGroupTypeResult.isRight());
+        assertEquals(StorageOperationStatus.MATCH_NOT_FOUND, updateGroupTypeResult.right().value());
+    }
+    
+    @Test
+    public void updateGroupTypeWithCapability_FailedDueToCapabilityChangeTypeAttempt() {
+        createRootGroupTypeNode();
+
+        PropertyDefinition property = buildProperty("vfc_instance_group_reference", null, "Ability to recognize capability per vfc instance group on vnf instance");
+
+        Map<String, PropertyDefinition> capTypeProperties = new HashMap<>();
+        capTypeProperties.put("vfc_instance_group_reference", property);
+        CapabilityTypeDefinition capabilityTypeDef = createCapabilityType(capTypeProperties);
+        Either<CapabilityTypeData, TitanOperationStatus> capabilityTypeResult = titanDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), capabilityTypeDef.getType(), CapabilityTypeData.class);
+        extractVal(capabilityTypeResult);
+
+        GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
+        groupTypeDefinition.setDerivedFrom(TOSCA_GROUPS_ROOT);
+        groupTypeDefinition.setDescription("groups l3-networks in network collection");
+        groupTypeDefinition.setType("org.openecomp.groups.NetworkCollection");
+
+        Map<String, CapabilityDefinition> mapCapabilities = new HashMap<>();
+        property.setValue("new_value");
+        ComponentInstanceProperty capDefProperty = new ComponentInstanceProperty(property);
+        CapabilityDefinition capabilityDef = buildCapabilityDefintion(asList(capDefProperty));
+        mapCapabilities.put("vlan_assignment", capabilityDef);
+        groupTypeDefinition.setCapabilities(mapCapabilities);
+
+        Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition);
+        assertTrue(addGroupTypeResult.isLeft());
+        
+        GroupTypeDefinition newGroupTypeDefinition = new GroupTypeDefinition();
+        newGroupTypeDefinition.setDerivedFrom(TOSCA_GROUPS_ROOT);
+        newGroupTypeDefinition.setDescription("groups l3-networks in network collection");
+        newGroupTypeDefinition.setType("org.openecomp.groups.NetworkCollection");
+        
+        Map<String, CapabilityDefinition> updatedMapCapabilities = new HashMap<>();
+        property.setValue("new_value");
+        ComponentInstanceProperty newCapDefProperty = new ComponentInstanceProperty(property);
+        CapabilityDefinition updatedCapabilityDef = buildCapabilityDefintion(asList(newCapDefProperty));
+        updatedCapabilityDef.setType("Another type");
+        updatedMapCapabilities.put("vlan_assignment", updatedCapabilityDef);
+        newGroupTypeDefinition.setCapabilities(updatedMapCapabilities);
+        
+        Either<GroupTypeDefinition, StorageOperationStatus> updateGroupTypeResult =  groupTypeOperation.updateGroupType(newGroupTypeDefinition,  addGroupTypeResult.left().value());
+        assertTrue(updateGroupTypeResult.isRight());
+        assertEquals(StorageOperationStatus.MATCH_NOT_FOUND, updateGroupTypeResult.right().value());
+    }
+    
+    @Test
+    public void updateGroupTypeWithCapability_Success() {
+        createRootGroupTypeNode();
+
+        PropertyDefinition property = buildProperty("vfc_instance_group_reference", null, "Ability to recognize capability per vfc instance group on vnf instance");
+
+        Map<String, PropertyDefinition> capTypeProperties = new HashMap<>();
+        capTypeProperties.put("vfc_instance_group_reference", property);
+        CapabilityTypeDefinition capabilityTypeDef = createCapabilityType(capTypeProperties);
+        Either<CapabilityTypeData, TitanOperationStatus> capabilityTypeResult = titanDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), capabilityTypeDef.getType(), CapabilityTypeData.class);
+        extractVal(capabilityTypeResult);
+
+        GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
+        groupTypeDefinition.setDerivedFrom(TOSCA_GROUPS_ROOT);
+        groupTypeDefinition.setDescription("groups l3-networks in network collection");
+        groupTypeDefinition.setType("org.openecomp.groups.NetworkCollection");
+
+        Map<String, CapabilityDefinition> mapCapabilities = new HashMap<>();
+        property.setValue("new_value");
+        ComponentInstanceProperty capDefProperty = new ComponentInstanceProperty(property);
+        CapabilityDefinition capabilityDef = buildCapabilityDefintion(asList(capDefProperty));
+        mapCapabilities.put("vlan_assignment", capabilityDef);
+        groupTypeDefinition.setCapabilities(mapCapabilities);
+
+        Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition);
+        assertTrue(addGroupTypeResult.isLeft());
+        
+        GroupTypeDefinition newGroupTypeDefinition = new GroupTypeDefinition();
+        newGroupTypeDefinition.setDerivedFrom(TOSCA_GROUPS_ROOT);
+        newGroupTypeDefinition.setDescription("groups l3-networks in network collection");
+        newGroupTypeDefinition.setType("org.openecomp.groups.NetworkCollection");
+        
+        Map<String, CapabilityDefinition> updatedMapCapabilities = new HashMap<>();
+        property.setValue("another_value");
+        ComponentInstanceProperty newCapDefProperty = new ComponentInstanceProperty(property);
+        CapabilityDefinition updatedCapabilityDef = buildCapabilityDefintion(asList(newCapDefProperty));
+        updatedMapCapabilities.put("vlan_assignment", updatedCapabilityDef);
+        newGroupTypeDefinition.setCapabilities(updatedMapCapabilities);
+        
+        Either<GroupTypeDefinition, StorageOperationStatus> updateGroupTypeResult =  groupTypeOperation.updateGroupType(newGroupTypeDefinition,  addGroupTypeResult.left().value());
+        assertTrue(updateGroupTypeResult.isLeft());
+    }
+
+    @Test
+    public void testUpdateGroupTypeWithDerivedFromEdge() {
+        createRootGroupTypeNode();
+
+        GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
         groupTypeDefinition.setDescription("groups l2-networks in network collection");
         groupTypeDefinition.setType("org.openecomp.groups.PrivateCollection");
         groupTypeDefinition.setVersion("1.0");
-        
+
         List<PropertyDefinition> properties = singletonList(
                 buildProperty("network_collection_type", "l2-network", "network collection type, defined with default value"));
         
         groupTypeDefinition.setProperties(properties );
         
         Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition, true);
-        assertEquals("check group type added", true, addGroupTypeResult.isLeft());
+        assertTrue("check group type added", addGroupTypeResult.isLeft());
         compareBetweenCreatedToSent(groupTypeDefinition, addGroupTypeResult.left().value());
         
         addGroupTypeResult = groupTypeOperation.getGroupTypeByTypeAndVersion("org.openecomp.groups.PrivateCollection", "1.0");
-        assertEquals("check group type added", true, addGroupTypeResult.isLeft());
+        assertTrue("check group type added", addGroupTypeResult.isLeft());
         compareBetweenCreatedToSent(groupTypeDefinition, addGroupTypeResult.left().value());
  
-        Either<GroupTypeDefinition, StorageOperationStatus> upgradeResult = groupTypeOperation.upgradeGroupType(groupTypeDefinition, groupTypeDefinition, true);
+        Either<GroupTypeDefinition, StorageOperationStatus> upgradeResult = groupTypeOperation.updateGroupType(groupTypeDefinition, groupTypeDefinition);
         assertNotNull(upgradeResult);
         assertTrue(upgradeResult.isLeft());
     }
     
     @Test
-    public void testUpgradeNonExistingGroupType() {
+    public void testUpdateNonExistingGroupType() {
         GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
         groupTypeDefinition.setDerivedFrom(TOSCA_GROUPS_ROOT);
         groupTypeDefinition.setDescription("groups l2-networks in network collection");
         groupTypeDefinition.setType("org.openecomp.groups.MyCollection");
         groupTypeDefinition.setVersion("1.0");
                              
-        Either<GroupTypeDefinition, StorageOperationStatus> upgradeResult = groupTypeOperation.upgradeGroupType(groupTypeDefinition, groupTypeDefinition, true);
+        Either<GroupTypeDefinition, StorageOperationStatus> upgradeResult = groupTypeOperation.updateGroupType(groupTypeDefinition, groupTypeDefinition);
         assertNotNull(upgradeResult);
         assertTrue(upgradeResult.isRight());
     }
     
     @Test
-    public void testUpgradeNotDerivedGroupType() {
+    public void testUpdateNotDerivedGroupType() {
         GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
         groupTypeDefinition.setDescription("groups social-networks in school");
         groupTypeDefinition.setType("org.openecomp.groups.Teachers");
         groupTypeDefinition.setVersion("1.0");
         
         Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition, true);
-        assertEquals("check group type added", true, addGroupTypeResult.isLeft());
+        assertTrue("check group type added", addGroupTypeResult.isLeft());
         compareBetweenCreatedToSent(groupTypeDefinition, addGroupTypeResult.left().value());
               
-        Either<GroupTypeDefinition, StorageOperationStatus> upgradeResult = groupTypeOperation.upgradeGroupType(groupTypeDefinition, groupTypeDefinition, true);
+        Either<GroupTypeDefinition, StorageOperationStatus> upgradeResult = groupTypeOperation.updateGroupType(groupTypeDefinition, groupTypeDefinition);
         assertNotNull(upgradeResult);
         assertTrue(upgradeResult.isLeft());
-        assertEquals(groupTypeDefinition, upgradeResult.left().value());
+        assertThat(groupTypeDefinition).isEqualToIgnoringGivenFields(upgradeResult.left().value(), "properties", "capabilities");
     }
     
     @Test
-    public void testUpgradeGroupTypeWithNonExistingParent() {
+    public void testUpdateGroupTypeWithNonExistingParent() {
         GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
         groupTypeDefinition.setDescription("groups social-networks in work");
         groupTypeDefinition.setType("org.openecomp.groups.Cowokers");
         groupTypeDefinition.setVersion("1.0");
         
         Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition, true);
-        assertEquals("check group type added", true, addGroupTypeResult.isLeft());
+        assertTrue("check group type added", addGroupTypeResult.isLeft());
         compareBetweenCreatedToSent(groupTypeDefinition, addGroupTypeResult.left().value());
               
         groupTypeDefinition.setDerivedFrom("Non.existing.parent");
-        Either<GroupTypeDefinition, StorageOperationStatus> upgradeResult = groupTypeOperation.upgradeGroupType(groupTypeDefinition, groupTypeDefinition, true);
+        Either<GroupTypeDefinition, StorageOperationStatus> upgradeResult = groupTypeOperation.updateGroupType(groupTypeDefinition, groupTypeDefinition);
         assertNotNull(upgradeResult);
         assertTrue(upgradeResult.isRight());
     }
@@ -240,23 +477,25 @@
         groupTypeDefinition.setVersion("1.0");
         
         Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(groupTypeDefinition, true);
-        assertEquals("check group type added", true, addGroupTypeResult.isLeft());
+        assertTrue("check group type added", addGroupTypeResult.isLeft());
         compareBetweenCreatedToSent(groupTypeDefinition, addGroupTypeResult.left().value());
         
         GroupTypeDefinition parentGroupTypeDefinition = new GroupTypeDefinition();
         parentGroupTypeDefinition.setDescription("groups social-networks in university");
         parentGroupTypeDefinition.setType("org.openecomp.groups.Parents");
         parentGroupTypeDefinition.setVersion("1.0");
+        parentGroupTypeDefinition.setHighestVersion(true);
+
         
         Either<GroupTypeDefinition, StorageOperationStatus> addParentGroupTypeResult =  groupTypeOperation.addGroupType(parentGroupTypeDefinition, true);
-        assertEquals("check group type added", true, addParentGroupTypeResult.isLeft());
+        assertTrue("check group type added", addParentGroupTypeResult.isLeft());
         compareBetweenCreatedToSent(parentGroupTypeDefinition, addParentGroupTypeResult.left().value());
               
         groupTypeDefinition.setDerivedFrom("org.openecomp.groups.Parents");
-        Either<GroupTypeDefinition, StorageOperationStatus> upgradeResult = groupTypeOperation.upgradeGroupType(groupTypeDefinition, groupTypeDefinition, true);
+        Either<GroupTypeDefinition, StorageOperationStatus> upgradeResult = groupTypeOperation.updateGroupType(groupTypeDefinition, addGroupTypeResult.left().value());
         assertNotNull(upgradeResult);
         assertTrue(upgradeResult.isLeft());
-        assertEquals(groupTypeDefinition, upgradeResult.left().value());
+        assertThat(groupTypeDefinition).isEqualToIgnoringGivenFields(upgradeResult.left().value(), "properties", "capabilities");
     }
     
     
@@ -271,8 +510,8 @@
     
     private GroupTypeData createRootGroupTypeNode() {
         GroupTypeDefinition rootGroupDefinition = createRootGroupDefinition();
-        Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(rootGroupDefinition, true);
-        assertEquals("check group type added", true, addGroupTypeResult.isLeft());
+        Either<GroupTypeDefinition, StorageOperationStatus> addGroupTypeResult =  groupTypeOperation.addGroupType(rootGroupDefinition, false);
+        assertTrue("check group type added", addGroupTypeResult.isLeft());
         
         Either<GroupTypeData, TitanOperationStatus> groupTypeResult = titanDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), rootGroupDefinition.getType(), GroupTypeData.class);
         return extractVal(groupTypeResult);        
@@ -282,6 +521,7 @@
         GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
         groupTypeDefinition.setDescription("The TOSCA Group Type all other TOSCA Group Types derive from");
         groupTypeDefinition.setType(TOSCA_GROUPS_ROOT);
+        groupTypeDefinition.setHighestVersion(true);
         return groupTypeDefinition;
     }
 
@@ -289,23 +529,41 @@
         GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition();
         groupTypeDefinition.setDescription("description for type " + type);
         groupTypeDefinition.setType(type);
+        groupTypeDefinition.setName(type + "name");
+        groupTypeDefinition.setIcon(type + "icon");
         return groupTypeDefinition;
     }
     
-    private CapabilityTypeDefinition createCapabilityType() {
+    private CapabilityTypeDefinition createCapabilityType(Map<String, PropertyDefinition> properties) {
+        CapabilityTypeDefinition rootCapabilityTypeDefinition = new CapabilityTypeDefinition();
+        rootCapabilityTypeDefinition.setType("tosca.capabilities.Root");
+        rootCapabilityTypeDefinition.setDescription("Dummy root type");
+        rootCapabilityTypeDefinition.setVersion("1.0");
+        capabilityTypeOperation.addCapabilityType(rootCapabilityTypeDefinition, true);
+
+
+        CapabilityTypeDefinition parentCapabilityTypeDefinition = new CapabilityTypeDefinition();
+        parentCapabilityTypeDefinition.setType("tosca.capabilities.Parent");
+        parentCapabilityTypeDefinition.setDescription("Dummy parent type");
+        parentCapabilityTypeDefinition.setDerivedFrom("tosca.capabilities.Root");
+        parentCapabilityTypeDefinition.setVersion("1.0");
+        PropertyDefinition property = buildProperty("parentProp", "any", "Description");
+        Map<String, PropertyDefinition> capTypeProperties = new HashMap<>();
+        capTypeProperties.put("parent_prop", property);
+        parentCapabilityTypeDefinition.setProperties(capTypeProperties);
+        capabilityTypeOperation.addCapabilityType(parentCapabilityTypeDefinition, true);
+
+
         CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition();
         capabilityTypeDefinition.setDescription("ability to expose routing information of the internal network");
         capabilityTypeDefinition.setType("org.openecomp.capabilities.VLANAssignment");
         capabilityTypeDefinition.setVersion("1.0");
-        
-        Map<String, PropertyDefinition> properties = new HashMap<>();
-        properties.put("vfc_instance_group_reference",
-                buildProperty("vfc_instance_group_reference", null, "Ability to recognize capability per vfc instance group on vnf instance"));
- 
+        capabilityTypeDefinition.setDerivedFrom("tosca.capabilities.Parent");
+
         capabilityTypeDefinition.setProperties(properties);
 
         Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityTypeResult = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
-        assertEquals("check capability type added", true, addCapabilityTypeResult.isLeft());
+        assertTrue("check capability type added", addCapabilityTypeResult.isLeft());
 
         CapabilityTypeDefinition capabilityTypeAdded = addCapabilityTypeResult.left().value();
         compareBetweenCreatedToSent(capabilityTypeDefinition, capabilityTypeAdded);
@@ -313,6 +571,15 @@
         return capabilityTypeDefinition;
     }
     
+    private CapabilityDefinition buildCapabilityDefintion(List<ComponentInstanceProperty> properties) {
+        CapabilityDefinition capabilityDefinition = new CapabilityDefinition();
+        capabilityDefinition.setName("vlan_assignment");
+        capabilityDefinition.setDescription("ability to expose routing information of the internal network");
+        capabilityDefinition.setType("org.openecomp.capabilities.VLANAssignment");
+        capabilityDefinition.setProperties(properties);
+        return capabilityDefinition;
+    }
+
     private PropertyDefinition buildProperty(String name, String defaultValue, String description) {
         PropertyDefinition property = new PropertyDefinition();
         property.setName(name);
@@ -346,5 +613,201 @@
         
         return t;
     }
+
+    private void cleanUp() {
+        Either<TitanGraph, TitanOperationStatus> graphResult = titanDao.getGraph();
+        TitanGraph graph = graphResult.left().value();
+
+        Iterable<TitanVertex> vertices = graph.query().vertices();
+        if (vertices != null) {
+            Iterator<TitanVertex> iterator = vertices.iterator();
+            while (iterator.hasNext()) {
+                TitanVertex vertex = iterator.next();
+                vertex.remove();
+            }
+
+        }
+        titanDao.commit();
+    }
+
+
+    @Test
+    public void updateGroupType_returnNotFoundErrorIfTryingToUpdateANonExistingType() {
+        GroupTypeDefinition currType = createGroupTypeDef();
+        GroupTypeDefinition updatedType = createGroupTypeDef();
+        Either<GroupTypeDefinition, StorageOperationStatus> updatedGroupTypeRes = groupTypeOperation.updateGroupType(updatedType, currType);
+        assertThat(updatedGroupTypeRes.right().value()).isEqualTo(StorageOperationStatus.NOT_FOUND);
+    }
+
+    @Test
+    public void updateGroupType_basicFields() {
+        GroupTypeDefinition createdType = createGroupTypeDef("type1", "description1", NULL_STRING);
+        Either<GroupTypeDefinition, StorageOperationStatus> currGroupType = groupTypeOperation.addGroupType(createdType);
+
+        GroupTypeDefinition updatedType = createGroupTypeDef("type1", "description2", NULL_STRING);
+        updatedType.setName("newName");
+        updatedType.setIcon("icon");
+        groupTypeOperation.updateGroupType(updatedType, currGroupType.left().value());
+
+        Either<GroupTypeDefinition, StorageOperationStatus> fetchedUpdatedType = groupTypeOperation.getLatestGroupTypeByType(createdType.getType());
+        GroupTypeDefinition fetchedGroupType = fetchedUpdatedType.left().value();
+        assertThat(fetchedGroupType.getProperties()).isEmpty();
+        assertThat(fetchedGroupType)
+                .isEqualToIgnoringGivenFields(updatedType, "properties", "capabilities");
+
+    }
+
+    @Test
+    public void updateGroupType_updatePropertiesType_FailedDueAttemptToChangePropertyType() {
+        PropertyDefinition prop1 = createSimpleProperty("val1", "prop1", "string");
+        GroupTypeDefinition groupType = createGroupTypeDef(prop1);
+        Either<GroupTypeDefinition, StorageOperationStatus> currGroupType = groupTypeOperation.addGroupType(groupType);
+
+        PropertyDefinition updatedProp1 = duplicateProperty(prop1, "newVal1", "int");
+        PropertyDefinition prop3 = createSimpleProperty("val3", "prop3", "string");
+        GroupTypeDefinition updatedGroupType = createGroupTypeDef(updatedProp1, prop3);
+
+        Either<GroupTypeDefinition, StorageOperationStatus> updatedGroupTypeRetrieved = groupTypeOperation.updateGroupType(updatedGroupType, currGroupType.left().value());
+        assertEquals(StorageOperationStatus.MATCH_NOT_FOUND, updatedGroupTypeRetrieved.right().value());
+    }
     
+    @Test
+    public void validateGroupType_FailedDueAttempToCreateGroupTypeWithPropertyWhichTypeIsDifferentFromTypeOfParentPropertyWithTheSameName() {
+        GroupTypeDefinition rootGroupType = createGroupTypeDef();
+        Either<GroupTypeDefinition, StorageOperationStatus> rootGroupTypeRes = groupTypeOperation.addGroupType(rootGroupType);
+        assertTrue(rootGroupTypeRes.isLeft());
+        
+        PropertyDefinition prop = createSimpleProperty("val1", "prop", "string");
+        GroupTypeDefinition groupType1 = createGroupTypeDef("type1", "descr1", rootGroupType.getType(), prop);
+        Either<GroupTypeDefinition, StorageOperationStatus> groupType1Res = groupTypeOperation.addGroupType(groupType1);
+        assertTrue(groupType1Res.isLeft());
+        
+        PropertyDefinition prop1 = createSimpleProperty("33", "prop", "int");
+        PropertyDefinition prop2 = createSimpleProperty("val2", "prop2", "string");
+        GroupTypeDefinition groupType2 = createGroupTypeDef("type2", "descr", groupType1.getType(), prop1, prop2);
+        
+        Either<GroupTypeDefinition, StorageOperationStatus> updatedGroupTypeRetrieved = groupTypeOperation.validateUpdateProperties(groupType2);
+        assertEquals(StorageOperationStatus.PROPERTY_NAME_ALREADY_EXISTS, updatedGroupTypeRetrieved.right().value());
+    }
+
+    @Test
+    public void updateGroupType_derivedFrom_whenNoPrevDerivedFrom_updateToNewDerivedFrom() {
+        GroupTypeDefinition rootGroupType = createGroupTypeDef();
+        GroupTypeDefinition groupType1 = createGroupTypeDef("type1", "descr", NULL_STRING);
+        GroupTypeDefinition updatedGroupType = createGroupTypeDef("type1", "descr", rootGroupType.getType());
+        groupTypeOperation.addGroupType(rootGroupType);
+        Either<GroupTypeDefinition, StorageOperationStatus> currGroupType = groupTypeOperation.addGroupType(groupType1);
+        groupTypeOperation.updateGroupType(updatedGroupType, currGroupType.left().value());
+
+        Either<GroupTypeDefinition, StorageOperationStatus> latestGroupType = groupTypeOperation.getLatestGroupTypeByType(groupType1.getType());
+        assertThat(latestGroupType.left().value().getDerivedFrom()).isEqualTo(rootGroupType.getType());
+        verifyDerivedFromNodeEqualsToRootGroupType(rootGroupType, latestGroupType.left().value().getUniqueId());
+    }
+
+    @Test
+    public void updateGroupType_derivedFrom_updateToNullDerivedFrom_derivedFromDeleted_Failed() {
+        GroupTypeDefinition rootGroupType = createGroupTypeDef();
+        GroupTypeDefinition groupType1 = createGroupTypeDef("type1", "descr", rootGroupType.getType());
+        GroupTypeDefinition updatedGroupType = createGroupTypeDef("type1", "descr", null, new PropertyDefinition[]{});
+        groupTypeOperation.addGroupType(rootGroupType);
+        Either<GroupTypeDefinition, StorageOperationStatus> currGroupType = groupTypeOperation.addGroupType(groupType1);
+
+        Either<GroupTypeDefinition, StorageOperationStatus> updateGroupTypeRes = groupTypeOperation.updateGroupType(updatedGroupType, currGroupType.left().value());
+        assertThat(updateGroupTypeRes.right().value()).isEqualTo(StorageOperationStatus.NOT_FOUND);
+
+        Either<GroupTypeDefinition, StorageOperationStatus> latestGroupType = groupTypeOperation.getLatestGroupTypeByType(groupType1.getType());
+        assertThat(latestGroupType.left().value().getDerivedFrom()).isEqualTo(rootGroupType.getType());
+    }
+
+    @Test
+    public void updateGroupType_updateDerivedFrom() {
+        GroupTypeDefinition rootGroupType = createGroupTypeDef();
+        GroupTypeDefinition derivedType1 = createGroupTypeDef("derivedType1", "descr", rootGroupType.getType());
+        GroupTypeDefinition groupType1 = createGroupTypeDef("type1", "descr", rootGroupType.getType());
+        GroupTypeDefinition updatedGroupType = createGroupTypeDef("type1", "descr", derivedType1.getType());
+
+        groupTypeOperation.addGroupType(rootGroupType);
+        groupTypeOperation.addGroupType(derivedType1);
+        Either<GroupTypeDefinition, StorageOperationStatus> currGroupType = groupTypeOperation.addGroupType(groupType1);
+
+        groupTypeOperation.updateGroupType(updatedGroupType, currGroupType.left().value());
+
+        Either<GroupTypeDefinition, StorageOperationStatus> latestGroupType = groupTypeOperation.getLatestGroupTypeByType(groupType1.getType());
+        assertThat(latestGroupType.left().value().getDerivedFrom()).isEqualTo(derivedType1.getType());
+    }
+    
+    @Test
+    public void updateGroupType_updateDerivedFrom_CauseEndlessRecursion() {
+        GroupTypeDefinition rootGroupType = createGroupTypeDef();
+        GroupTypeDefinition derivedType1 = createGroupTypeDef("derivedType1", "descr", rootGroupType.getType());
+        GroupTypeDefinition groupType1 = createGroupTypeDef("type1", "descr", derivedType1.getType());
+        GroupTypeDefinition updatedGroupType = createGroupTypeDef("derivedType1", "descr", groupType1.getType());
+
+        groupTypeOperation.addGroupType(rootGroupType);
+        Either<GroupTypeDefinition, StorageOperationStatus> currGroupType = groupTypeOperation.addGroupType(derivedType1);
+        groupTypeOperation.addGroupType(groupType1);
+
+        Either<GroupTypeDefinition, StorageOperationStatus> updateResult = groupTypeOperation.updateGroupType(updatedGroupType, currGroupType.left().value());
+        assertThat(updateResult.right().value()).isEqualTo(StorageOperationStatus.GENERAL_ERROR);
+
+        Either<GroupTypeDefinition, StorageOperationStatus> latestGroupType = groupTypeOperation.getLatestGroupTypeByType(updatedGroupType.getType());
+        assertThat(latestGroupType.left().value().getDerivedFrom()).isEqualTo(rootGroupType.getType());
+    }
+
+    private PropertyDefinition duplicateProperty(PropertyDefinition prop1, String updatedValue, String updatedType) {
+        PropertyDefinition updatedProp1 = new PropertyDefinition(prop1);
+        updatedProp1.setUniqueId(null);
+        updatedProp1.setDefaultValue(updatedValue);
+        updatedProp1.setType(updatedType);
+        return updatedProp1;
+    }
+
+    private void verifyDerivedFromNodeEqualsToRootGroupType(GroupTypeDefinition rootGroupType, String parentGroupId) {
+        Either<ImmutablePair<GroupTypeData, GraphEdge>, TitanOperationStatus> derivedFromRelation = titanDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupType), parentGroupId, GraphEdgeLabels.DERIVED_FROM,
+                NodeTypeEnum.GroupType, GroupTypeData.class);
+        assertThat(derivedFromRelation.left().value().getLeft().getGroupTypeDataDefinition())
+                .isEqualToComparingFieldByField(rootGroupType);
+    }
+
+    private void verifyDerivedFromRelationDoesntExist(String parentGroupId) {
+        Either<ImmutablePair<GroupTypeData, GraphEdge>, TitanOperationStatus> derivedFromRelation = titanDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupType), parentGroupId, GraphEdgeLabels.DERIVED_FROM,
+                NodeTypeEnum.GroupType, GroupTypeData.class);
+        assertThat(derivedFromRelation.right().value())
+                .isEqualTo(TitanOperationStatus.NOT_FOUND);
+    }
+
+    private GroupTypeDefinition createGroupTypeDef() {
+        return createGroupTypeDef("tosca.groups.Root", "description: The TOSCA Group Type all other TOSCA Group Types derive from", null, new PropertyDefinition[]{});
+    }
+
+    private GroupTypeDefinition createGroupTypeDef(PropertyDefinition ... props) {
+        return createGroupTypeDef("tosca.groups.Root",  null, props);
+    }
+
+    private GroupTypeDefinition createGroupTypeDef(String type, String derivedFrom, PropertyDefinition ... props) {
+        GroupTypeDefinition groupType = createGroupTypeDef(type, "description: The TOSCA Group Type all other TOSCA Group Types derive from", derivedFrom);
+        groupType.setProperties(asList(props));
+        return groupType;
+    }
+
+    private GroupTypeDefinition createGroupTypeDef(String type, String description, String derivedFrom) {
+        return createGroupTypeDef(type, description, derivedFrom, null);
+    }
+
+    private GroupTypeDefinition createGroupTypeDef(String type, String description, String derivedFrom,  PropertyDefinition ... props) {
+        GroupTypeDataDefinition groupTypeDataDefinition = new GroupTypeDataDefinition();
+        groupTypeDataDefinition.setDescription(description);
+        groupTypeDataDefinition.setType(type);
+        groupTypeDataDefinition.setName(type + "name");
+        groupTypeDataDefinition.setIcon(type + "icon");
+        groupTypeDataDefinition.setDerivedFrom(derivedFrom);
+        GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition(groupTypeDataDefinition);
+        groupTypeDefinition.setHighestVersion(true);
+        groupTypeDefinition.setVersion("1.0");
+        if (props != null) {
+            groupTypeDefinition.setProperties(asList(props));
+        }
+        return groupTypeDefinition;
+    }
+
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperationTest.java
index 46db317..61504db 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperationTest.java
@@ -20,18 +20,7 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyMap;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.List;
-
+import fj.data.Either;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -48,199 +37,204 @@
 import org.openecomp.sdc.be.resources.data.HeatParameterData;
 import org.openecomp.sdc.be.resources.data.HeatParameterValueData;
 
-import fj.data.Either;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.when;
 
 public class HeatParametersOperationTest extends ModelTestBase {
 
-	HeatParametersOperation heatParametersOperation = new HeatParametersOperation();
+    HeatParametersOperation heatParametersOperation = new HeatParametersOperation();
 
-	TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class);
+    TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class);
 
-	@Before
-	public void setup() {
-		heatParametersOperation.setTitanGenericDao(titanGenericDao);
+    @Before
+    public void setup() {
+        heatParametersOperation.setTitanGenericDao(titanGenericDao);
 
-	}
+    }
 
-	@Test
-	public void addPropertyToResourceTest() {
+    @Test
+    public void addPropertyToResourceTest() {
 
-		String propName = "myProp";
-		HeatParameterDefinition property = buildHeatPropertyDefinition();
+        String propName = "myProp";
+        HeatParameterDefinition property = buildHeatPropertyDefinition();
 
-		HeatParameterData propertyData = new HeatParameterData(property);
+        HeatParameterData propertyData = new HeatParameterData(property);
 
-		Either<HeatParameterData, TitanOperationStatus> either = Either.left(propertyData);
+        Either<HeatParameterData, TitanOperationStatus> either = Either.left(propertyData);
 
-		GraphRelation graphRelation = new GraphRelation();
-		Either<GraphRelation, TitanOperationStatus> relationResult = Either.left(graphRelation);
+        GraphRelation graphRelation = new GraphRelation();
+        Either<GraphRelation, TitanOperationStatus> relationResult = Either.left(graphRelation);
 
-		when(titanGenericDao.createNode(any(HeatParameterData.class), eq(HeatParameterData.class))).thenReturn(either);
-		when(titanGenericDao.createRelation(any(GraphNode.class), (GraphNode) any(GraphNode.class), eq(GraphEdgeLabels.HEAT_PARAMETER), anyMap())).thenReturn(relationResult);
+        when(titanGenericDao.createNode(any(HeatParameterData.class), eq(HeatParameterData.class))).thenReturn(either);
+        when(titanGenericDao.createRelation(any(GraphNode.class), any(GraphNode.class), eq(GraphEdgeLabels.HEAT_PARAMETER), anyMap())).thenReturn(relationResult);
 
-		Either<HeatParameterData, TitanOperationStatus> result = heatParametersOperation.addPropertyToGraph(propName, property, "resourceId.artifactId", NodeTypeEnum.ArtifactRef);
+        Either<HeatParameterData, TitanOperationStatus> result = heatParametersOperation.addPropertyToGraph(propName, property, "resourceId.artifactId", NodeTypeEnum.ArtifactRef);
 
-		assertTrue(result.isLeft());
+        assertTrue(result.isLeft());
 
-	}
+    }
 
-	@Test
-	public void addPropertyListToResourceTest() {
+    @Test
+    public void addPropertyListToResourceTest() {
 
-		HeatParameterDefinition property = buildHeatPropertyDefinition();
-		HeatParameterDefinition property2 = buildHeatPropertyDefinition();
-		property2.setName("p2");
+        HeatParameterDefinition property = buildHeatPropertyDefinition();
+        HeatParameterDefinition property2 = buildHeatPropertyDefinition();
+        property2.setName("p2");
 
-		List<HeatParameterDefinition> parameters = new ArrayList<HeatParameterDefinition>();
-		parameters.add(property);
-		parameters.add(property2);
+        List<HeatParameterDefinition> parameters = new ArrayList<>();
+        parameters.add(property);
+        parameters.add(property2);
 
-		HeatParameterData propertyData = new HeatParameterData(property);
+        HeatParameterData propertyData = new HeatParameterData(property);
 
-		Either<HeatParameterData, TitanOperationStatus> either = Either.left(propertyData);
+        Either<HeatParameterData, TitanOperationStatus> either = Either.left(propertyData);
 
-		GraphRelation graphRelation = new GraphRelation();
-		Either<GraphRelation, TitanOperationStatus> relationResult = Either.left(graphRelation);
+        GraphRelation graphRelation = new GraphRelation();
+        Either<GraphRelation, TitanOperationStatus> relationResult = Either.left(graphRelation);
 
-		when(titanGenericDao.createNode(any(HeatParameterData.class), eq(HeatParameterData.class))).thenReturn(either);
-		when(titanGenericDao.createRelation(any(GraphNode.class), (GraphNode) any(GraphNode.class), eq(GraphEdgeLabels.HEAT_PARAMETER), anyMap())).thenReturn(relationResult);
+        when(titanGenericDao.createNode(any(HeatParameterData.class), eq(HeatParameterData.class))).thenReturn(either);
+        when(titanGenericDao.createRelation(any(GraphNode.class), any(GraphNode.class), eq(GraphEdgeLabels.HEAT_PARAMETER), anyMap())).thenReturn(relationResult);
 
-		StorageOperationStatus result = heatParametersOperation.addPropertiesToGraph(parameters, "resourceId.artifactId", NodeTypeEnum.ArtifactRef);
+        StorageOperationStatus result = heatParametersOperation.addPropertiesToGraph(parameters, "resourceId.artifactId", NodeTypeEnum.ArtifactRef);
 
-		assertEquals(StorageOperationStatus.OK, result);
+        assertEquals(StorageOperationStatus.OK, result);
 
-	}
+    }
 
-	@Test
-	public void testStringValues() {
-		assertTrue(heatParametersOperation.isValidValue(HeatParameterType.STRING, "50aaa"));
-	}
+    @Test
+    public void testStringValues() {
+        assertTrue(heatParametersOperation.isValidValue(HeatParameterType.STRING, "50aaa"));
+    }
 
-	@Test
-	public void testNumberValues() {
-		assertTrue(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "50"));
-		assertTrue(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "50.5"));
-		assertTrue(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "0x11"));
+    @Test
+    public void testNumberValues() {
+        assertTrue(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "50"));
+        assertTrue(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "50.5"));
+        assertTrue(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "0x11"));
 
-		assertFalse(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "aaa"));
-		assertFalse(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "?>!"));
-	}
+        assertFalse(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "aaa"));
+        assertFalse(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "?>!"));
+    }
 
-	@Test
-	public void testJsonValues() {
-		assertTrue(heatParametersOperation.isValidValue(HeatParameterType.JSON, "{ \"member\" : \"50\"}"));
-		HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.JSON.getType(), "{ \"member\" : \"50\"}");
-		StorageOperationStatus operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
-		assertEquals(StorageOperationStatus.OK, operationStatus);
-		assertEquals(HeatParameterType.JSON.getType(), propertyDefinition.getType());
+    @Test
+    public void testJsonValues() {
+        assertTrue(heatParametersOperation.isValidValue(HeatParameterType.JSON, "{ \"member\" : \"50\"}"));
+        HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.JSON.getType(), "{ \"member\" : \"50\"}");
+        StorageOperationStatus operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
+        assertEquals(StorageOperationStatus.OK, operationStatus);
+        assertEquals(HeatParameterType.JSON.getType(), propertyDefinition.getType());
 
-	}
+    }
 
-	@Test
-	public void testListValues() {
-		assertTrue(heatParametersOperation.isValidValue(HeatParameterType.COMMA_DELIMITED_LIST, "one, two"));
-		HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.COMMA_DELIMITED_LIST.getType(), "one, two");
-		StorageOperationStatus operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
-		assertEquals(StorageOperationStatus.OK, operationStatus);
-		assertEquals(HeatParameterType.COMMA_DELIMITED_LIST.getType(), propertyDefinition.getType());
-		assertEquals("one, two", propertyDefinition.getDefaultValue());
-	}
+    @Test
+    public void testListValues() {
+        assertTrue(heatParametersOperation.isValidValue(HeatParameterType.COMMA_DELIMITED_LIST, "one, two"));
+        HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.COMMA_DELIMITED_LIST.getType(), "one, two");
+        StorageOperationStatus operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
+        assertEquals(StorageOperationStatus.OK, operationStatus);
+        assertEquals(HeatParameterType.COMMA_DELIMITED_LIST.getType(), propertyDefinition.getType());
+        assertEquals("one, two", propertyDefinition.getDefaultValue());
+    }
 
-	@Test
-	public void testBooleanValues() {
+    @Test
+    public void testBooleanValues() {
 
-		String[] trueArray = { "true", "t", "1", "on", "y", "yes" };
-		String[] falseArray = { "false", "f", "0", "off", "n", "no" };
+        String[] trueArray = { "true", "t", "1", "on", "y", "yes" };
+        String[] falseArray = { "false", "f", "0", "off", "n", "no" };
 
-		for (int i = 0; i < trueArray.length; i++) {
-			assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, trueArray[i]));
-			HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), trueArray[i]);
-			StorageOperationStatus operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
-			assertEquals(StorageOperationStatus.OK, operationStatus);
-			assertEquals("true", propertyDefinition.getDefaultValue());
+        for (int i = 0; i < trueArray.length; i++) {
+            assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, trueArray[i]));
+            HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), trueArray[i]);
+            StorageOperationStatus operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
+            assertEquals(StorageOperationStatus.OK, operationStatus);
+            assertEquals("true", propertyDefinition.getDefaultValue());
 
-			assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, trueArray[i]));
-			propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), trueArray[i].toUpperCase());
-			operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
-			assertEquals(StorageOperationStatus.OK, operationStatus);
-			assertEquals("true", propertyDefinition.getDefaultValue());
+            assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, trueArray[i]));
+            propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), trueArray[i].toUpperCase());
+            operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
+            assertEquals(StorageOperationStatus.OK, operationStatus);
+            assertEquals("true", propertyDefinition.getDefaultValue());
 
-			assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, trueArray[i]));
-			propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), trueArray[i].toLowerCase());
-			operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
-			assertEquals(StorageOperationStatus.OK, operationStatus);
-			assertEquals("true", propertyDefinition.getDefaultValue());
-		}
+            assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, trueArray[i]));
+            propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), trueArray[i].toLowerCase());
+            operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
+            assertEquals(StorageOperationStatus.OK, operationStatus);
+            assertEquals("true", propertyDefinition.getDefaultValue());
+        }
 
-		for (int i = 0; i < falseArray.length; i++) {
-			assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, falseArray[i]));
-			HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), falseArray[i]);
-			StorageOperationStatus operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
-			assertEquals(StorageOperationStatus.OK, operationStatus);
-			assertEquals("false", propertyDefinition.getDefaultValue());
+        for (int i = 0; i < falseArray.length; i++) {
+            assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, falseArray[i]));
+            HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), falseArray[i]);
+            StorageOperationStatus operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
+            assertEquals(StorageOperationStatus.OK, operationStatus);
+            assertEquals("false", propertyDefinition.getDefaultValue());
 
-			assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, falseArray[i]));
-			propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), falseArray[i].toUpperCase());
-			operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
-			assertEquals(StorageOperationStatus.OK, operationStatus);
-			assertEquals("false", propertyDefinition.getDefaultValue());
+            assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, falseArray[i]));
+            propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), falseArray[i].toUpperCase());
+            operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
+            assertEquals(StorageOperationStatus.OK, operationStatus);
+            assertEquals("false", propertyDefinition.getDefaultValue());
 
-			assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, falseArray[i]));
-			propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), falseArray[i].toLowerCase());
-			operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
-			assertEquals(StorageOperationStatus.OK, operationStatus);
-			assertEquals("false", propertyDefinition.getDefaultValue());
-		}
+            assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, falseArray[i]));
+            propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), falseArray[i].toLowerCase());
+            operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition);
+            assertEquals(StorageOperationStatus.OK, operationStatus);
+            assertEquals("false", propertyDefinition.getDefaultValue());
+        }
 
-		assertFalse(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, "blabla"));
-		assertFalse(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, "2"));
-	}
+        assertFalse(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, "blabla"));
+        assertFalse(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, "2"));
+    }
 
-	private HeatParameterDefinition buildHeatPropertyDefinition() {
-		HeatParameterDefinition parameter = new HeatParameterDefinition();
+    private HeatParameterDefinition buildHeatPropertyDefinition() {
+        HeatParameterDefinition parameter = new HeatParameterDefinition();
 
-		parameter.setName("p1");
-		parameter.setType("string");
-		parameter.setDefaultValue("def");
-		parameter.setCurrentValue("current");
-		parameter.setDescription("description");
+        parameter.setName("p1");
+        parameter.setType("string");
+        parameter.setDefaultValue("def");
+        parameter.setCurrentValue("current");
+        parameter.setDescription("description");
 
-		return parameter;
-	}
+        return parameter;
+    }
 
-	private HeatParameterDefinition buildHeatBooleanPropertyDefinition(String type, String boolValue) {
-		HeatParameterDefinition parameter = new HeatParameterDefinition();
+    private HeatParameterDefinition buildHeatBooleanPropertyDefinition(String type, String boolValue) {
+        HeatParameterDefinition parameter = new HeatParameterDefinition();
 
-		parameter.setName("parameter1");
-		parameter.setType(type);
-		parameter.setDefaultValue(boolValue);
-		parameter.setDescription("description");
+        parameter.setName("parameter1");
+        parameter.setType(type);
+        parameter.setDefaultValue(boolValue);
+        parameter.setDescription("description");
 
-		return parameter;
-	}
+        return parameter;
+    }
 
-	@Test
-	public void addPropertyToResourceInstanceTest() {
+    @Test
+    public void addPropertyToResourceInstanceTest() {
 
-		HeatParameterDefinition property = buildHeatPropertyDefinition();
+        HeatParameterDefinition property = buildHeatPropertyDefinition();
 
-		HeatParameterValueData propertyData = new HeatParameterValueData();
-		propertyData.setUniqueId("bla");
-		propertyData.setValue("value1");
+        HeatParameterValueData propertyData = new HeatParameterValueData();
+        propertyData.setUniqueId("bla");
+        propertyData.setValue("value1");
 
-		Either<HeatParameterValueData, TitanOperationStatus> either = Either.left(propertyData);
+        Either<HeatParameterValueData, TitanOperationStatus> either = Either.left(propertyData);
 
-		GraphRelation graphRelation = new GraphRelation();
-		Either<GraphRelation, TitanOperationStatus> relationResult = Either.left(graphRelation);
+        GraphRelation graphRelation = new GraphRelation();
+        Either<GraphRelation, TitanOperationStatus> relationResult = Either.left(graphRelation);
 
-		when(titanGenericDao.createNode(any(HeatParameterValueData.class), eq(HeatParameterValueData.class))).thenReturn(either);
-		when(titanGenericDao.createRelation(any(GraphNode.class), any(GraphNode.class), eq(GraphEdgeLabels.PARAMETER_VALUE), anyMap())).thenReturn(relationResult);
-		when(titanGenericDao.createRelation(any(GraphNode.class), any(GraphNode.class), eq(GraphEdgeLabels.PARAMETER_IMPL), isNull())).thenReturn(relationResult);
+        when(titanGenericDao.createNode(any(HeatParameterValueData.class), eq(HeatParameterValueData.class))).thenReturn(either);
+        when(titanGenericDao.createRelation(any(GraphNode.class), any(GraphNode.class), eq(GraphEdgeLabels.PARAMETER_VALUE), anyMap())).thenReturn(relationResult);
+        when(titanGenericDao.createRelation(any(GraphNode.class), any(GraphNode.class), eq(GraphEdgeLabels.PARAMETER_IMPL), isNull())).thenReturn(relationResult);
 
-		Either<HeatParameterValueData, TitanOperationStatus> result = heatParametersOperation.addHeatValueToGraph(property, "artifactLabel", "resourceInstanceId.artifactId", "resourceInstanceId");
+        Either<HeatParameterValueData, TitanOperationStatus> result = heatParametersOperation.addHeatValueToGraph(property, "artifactLabel", "resourceInstanceId.artifactId", "resourceInstanceId");
 
-		assertTrue(result.isLeft());
+        assertTrue(result.isLeft());
 
-	}
+    }
 
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/InterfaceOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/InterfaceOperationTest.java
index ae79440..a50435b 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/InterfaceOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/InterfaceOperationTest.java
@@ -20,8 +20,8 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import static org.junit.Assert.assertTrue;
-
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -40,215 +40,215 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:application-context-test.xml")
 public class InterfaceOperationTest {
-	private static Logger log = LoggerFactory.getLogger(InterfaceOperationTest.class.getName());
-	private Gson prettyGson = new GsonBuilder().setPrettyPrinting().create();
+    private static final Logger log = LoggerFactory.getLogger(InterfaceOperationTest.class);
+    private Gson prettyGson = new GsonBuilder().setPrettyPrinting().create();
 
-	private static String USER_ID = "muUserId";
-	private static String CATEGORY_NAME = "category/mycategory";
-	// InterfaceLifecycleOperation interfaceOperation = new
-	// InterfaceLifecycleOperation();
+    private static String USER_ID = "muUserId";
+    private static String CATEGORY_NAME = "category/mycategory";
+    // InterfaceLifecycleOperation interfaceOperation = new
+    // InterfaceLifecycleOperation();
 
-	// TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class);
-	@javax.annotation.Resource(name = "titan-generic-dao")
-	private TitanGenericDao titanDao;
+    // TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class);
+    @javax.annotation.Resource(name = "titan-generic-dao")
+    private TitanGenericDao titanDao;
 
-	@javax.annotation.Resource(name = "interface-operation")
-	private InterfaceLifecycleOperation interfaceOperation;
+    @javax.annotation.Resource(name = "interface-operation")
+    private InterfaceLifecycleOperation interfaceOperation;
 
-	@javax.annotation.Resource(name = "property-operation")
-	private PropertyOperation propertyOperation;
+    @javax.annotation.Resource(name = "property-operation")
+    private PropertyOperation propertyOperation;
 
-	// @Resource(name = "artifact-operation")
-	// private ArtifactOperation artifactOperation;
+    // @Resource(name = "artifact-operation")
+    // private ArtifactOperation artifactOperation;
 
-	@Before
-	public void createUserAndCategory() {
-		deleteAndCreateCategory(CATEGORY_NAME);
-		deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID);
-	}
+    @Before
+    public void createUserAndCategory() {
+        deleteAndCreateCategory(CATEGORY_NAME);
+        deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID);
+    }
 
-	@BeforeClass
-	public static void setupBeforeClass() {
-		// ExternalConfiguration.setAppName("catalog-model");
-		// String appConfigDir = "src/test/resources/config/catalog-model";
-		// ConfigurationSource configurationSource = new
-		// FSConfigurationSource(ExternalConfiguration.getChangeListener(),
-		// appConfigDir);
+    @BeforeClass
+    public static void setupBeforeClass() {
+        // ExternalConfiguration.setAppName("catalog-model");
+        // String appConfigDir = "src/test/resources/config/catalog-model";
+        // ConfigurationSource configurationSource = new
+        // FSConfigurationSource(ExternalConfiguration.getChangeListener(),
+        // appConfigDir);
 
-		ModelTestBase.init();
+        ModelTestBase.init();
 
-	}
+    }
 
-	@Test
-	public void testDummy() {
+    @Test
+    public void testDummy() {
 
-		assertTrue(interfaceOperation != null);
+        assertNotNull(interfaceOperation);
 
-	}
+    }
 
-/*	@Test
-	public void addInterfaceToResourceTest() {
+/*    @Test
+    public void addInterfaceToResourceTest() {
 
-		String capabilityTypeName = "mycapability1";
-		String reqName = "host";
-		String reqNodeName = "tosca.nodes.Compute1";
-		String rootName = "Root100";
-		String softwareCompName = "tosca.nodes.SoftwareComponent";
-		String computeNodeName = "tosca.nodes.Compute";
-		String myResourceVersion = "300.0";
-		String reqRelationship = "myrelationship";
+        String capabilityTypeName = "mycapability1";
+        String reqName = "host";
+        String reqNodeName = "tosca.nodes.Compute1";
+        String rootName = "Root100";
+        String softwareCompName = "tosca.nodes.SoftwareComponent";
+        String computeNodeName = "tosca.nodes.Compute";
+        String myResourceVersion = "300.0";
+        String reqRelationship = "myrelationship";
 
-		ResourceOperationTest resourceOperationTest = new ResourceOperationTest();
-		resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation);
+        ResourceOperationTest resourceOperationTest = new ResourceOperationTest();
+        resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation);
 
-		Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "100.0", null, true, true);
+        Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "100.0", null, true, true);
 
-		String interfaceName = "standard";
-		InterfaceDefinition interfaceDefinition = buildInterfaceDefinition();
+        String interfaceName = "standard";
+        InterfaceDefinition interfaceDefinition = buildInterfaceDefinition();
 
-		Operation op = buildOperationDefinition();
-		Map<String, Operation> operations = new HashMap<String, Operation>();
-		operations.put("Create", op);
-		interfaceDefinition.setOperations(operations);
+        Operation op = buildOperationDefinition();
+        Map<String, Operation> operations = new HashMap<String, Operation>();
+        operations.put("Create", op);
+        interfaceDefinition.setOperations(operations);
 
-		Either<InterfaceDefinition, StorageOperationStatus> result = interfaceOperation.addInterfaceToResource(interfaceDefinition, rootResource.getUniqueId(), "standard");
+        Either<InterfaceDefinition, StorageOperationStatus> result = interfaceOperation.addInterfaceToResource(interfaceDefinition, rootResource.getUniqueId(), "standard");
 
-		assertTrue(result.isLeft());
-		log.debug("{}", result.left().value());
+        assertTrue(result.isLeft());
+        log.debug("{}", result.left().value());
 
-		Either<Resource, StorageOperationStatus> getResourceRes = resourceOperation.getResource(rootResource.getUniqueId());
-		assertTrue(getResourceRes.isLeft());
-		Resource resourceWithInterface = getResourceRes.left().value();
-		Map<String, InterfaceDefinition> interfaces = resourceWithInterface.getInterfaces();
-		assertNotNull(interfaces);
-		assertFalse(interfaces.isEmpty());
-		InterfaceDefinition interfaceDefinition2 = interfaces.get(interfaceName);
-		assertNotNull(interfaceDefinition2.getOperations());
-		assertFalse(interfaceDefinition2.getOperations().isEmpty());
+        Either<Resource, StorageOperationStatus> getResourceRes = resourceOperation.getResource(rootResource.getUniqueId());
+        assertTrue(getResourceRes.isLeft());
+        Resource resourceWithInterface = getResourceRes.left().value();
+        Map<String, InterfaceDefinition> interfaces = resourceWithInterface.getInterfaces();
+        assertNotNull(interfaces);
+        assertFalse(interfaces.isEmpty());
+        InterfaceDefinition interfaceDefinition2 = interfaces.get(interfaceName);
+        assertNotNull(interfaceDefinition2.getOperations());
+        assertFalse(interfaceDefinition2.getOperations().isEmpty());
 
-	}
+    }
 
-	@Test
-	public void updateInterfaceToResourceTest() {
+    @Test
+    public void updateInterfaceToResourceTest() {
 
-		String reqName = "host";
-		String rootName = "Root200";
-		String softwareCompName = "tosca.nodes.SoftwareComponent";
+        String reqName = "host";
+        String rootName = "Root200";
+        String softwareCompName = "tosca.nodes.SoftwareComponent";
 
-		ResourceOperationTest resourceOperationTest = new ResourceOperationTest();
-		resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation);
+        ResourceOperationTest resourceOperationTest = new ResourceOperationTest();
+        resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation);
 
-		Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "200.0", null, true, true);
+        Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "200.0", null, true, true);
 
-		String interfaceName = "standard";
-		InterfaceDefinition interfaceDefinition = buildInterfaceDefinition();
+        String interfaceName = "standard";
+        InterfaceDefinition interfaceDefinition = buildInterfaceDefinition();
 
-		Operation op = buildOperationDefinition();
-		Map<String, Operation> operations = new HashMap<String, Operation>();
-		operations.put("create", op);
-		interfaceDefinition.setOperations(operations);
+        Operation op = buildOperationDefinition();
+        Map<String, Operation> operations = new HashMap<String, Operation>();
+        operations.put("create", op);
+        interfaceDefinition.setOperations(operations);
 
-		Either<InterfaceDefinition, StorageOperationStatus> result = interfaceOperation.addInterfaceToResource(interfaceDefinition, rootResource.getUniqueId(), "standard");
+        Either<InterfaceDefinition, StorageOperationStatus> result = interfaceOperation.addInterfaceToResource(interfaceDefinition, rootResource.getUniqueId(), "standard");
 
-		ResourceMetadataData resourceData = new ResourceMetadataData();
-		resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId());
-		resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name());
-		Either<ResourceMetadataData, TitanOperationStatus> updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class);
-		assertTrue(updateNode.isLeft());
+        ResourceMetadataData resourceData = new ResourceMetadataData();
+        resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId());
+        resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name());
+        Either<ResourceMetadataData, TitanOperationStatus> updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class);
+        assertTrue(updateNode.isLeft());
 
-		Either<Resource, StorageOperationStatus> fetchRootResource = resourceOperation.getResource(rootResource.getUniqueId());
+        Either<Resource, StorageOperationStatus> fetchRootResource = resourceOperation.getResource(rootResource.getUniqueId());
 
-		assertTrue(fetchRootResource.isLeft());
-		String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value());
-		log.debug(rootResourceJson);
+        assertTrue(fetchRootResource.isLeft());
+        String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value());
+        log.debug(rootResourceJson);
 
-		Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, "400.0", rootResource.getName(), true, true);
+        Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, "400.0", rootResource.getName(), true, true);
 
-		assertTrue(result.isLeft());
-		log.debug("{}", result.left().value());
+        assertTrue(result.isLeft());
+        log.debug("{}", result.left().value());
 
-		addImplementationToOperation(op);
-		// String resourceId, String interfaceName, String
-		// operationName,Operation interf
+        addImplementationToOperation(op);
+        // String resourceId, String interfaceName, String
+        // operationName,Operation interf
 
-		Either<Operation, StorageOperationStatus> opResult = interfaceOperation.updateInterfaceOperation(softwareComponent.getUniqueId(), "standard", "create", op);
-		// PrintGraph pg = new PrintGraph();
-		// System.out.println(pg.buildGraphForWebgraphWiz(titanDao.getGraph().left().value()));
-		assertTrue(opResult.isLeft());
-		log.debug("{}", opResult.left().value());
+        Either<Operation, StorageOperationStatus> opResult = interfaceOperation.updateInterfaceOperation(softwareComponent.getUniqueId(), "standard", "create", op);
+        // PrintGraph pg = new PrintGraph();
+        // System.out.println(pg.buildGraphForWebgraphWiz(titanDao.getGraph().left().value()));
+        assertTrue(opResult.isLeft());
+        log.debug("{}", opResult.left().value());
 
-		Either<Resource, StorageOperationStatus> getResourceRes = resourceOperation.getResource(softwareComponent.getUniqueId());
-		assertTrue(getResourceRes.isLeft());
-		Resource resourceWithInterface = getResourceRes.left().value();
-		Map<String, InterfaceDefinition> interfaces = resourceWithInterface.getInterfaces();
-		assertNotNull(interfaces);
-		assertFalse(interfaces.isEmpty());
-		InterfaceDefinition interfaceDefinition2 = interfaces.get(interfaceName);
-		assertNotNull(interfaceDefinition2.getOperations());
-		assertFalse(interfaceDefinition2.getOperations().isEmpty());
-		Operation operation = interfaceDefinition2.getOperations().get("create");
-		assertNotNull(operation);
-		assertNotNull(operation.getImplementation());
-	}
+        Either<Resource, StorageOperationStatus> getResourceRes = resourceOperation.getResource(softwareComponent.getUniqueId());
+        assertTrue(getResourceRes.isLeft());
+        Resource resourceWithInterface = getResourceRes.left().value();
+        Map<String, InterfaceDefinition> interfaces = resourceWithInterface.getInterfaces();
+        assertNotNull(interfaces);
+        assertFalse(interfaces.isEmpty());
+        InterfaceDefinition interfaceDefinition2 = interfaces.get(interfaceName);
+        assertNotNull(interfaceDefinition2.getOperations());
+        assertFalse(interfaceDefinition2.getOperations().isEmpty());
+        Operation operation = interfaceDefinition2.getOperations().get("create");
+        assertNotNull(operation);
+        assertNotNull(operation.getImplementation());
+    }
 */
-	private void addImplementationToOperation(Operation op) {
-		ArtifactDataDefinition artifactDataDef = new ArtifactDataDefinition();
-		artifactDataDef.setArtifactChecksum("YTg2Mjg4MWJhNmI5NzBiNzdDFkMWI=");
-		artifactDataDef.setArtifactName("create_myRoot.sh");
-		artifactDataDef.setArtifactLabel("create_myRoot");
-		artifactDataDef.setArtifactType("SHELL");
-		artifactDataDef.setDescription("good description");
-		artifactDataDef.setEsId("esId");
-		artifactDataDef.setUniqueId(op.getUniqueId() + "." + artifactDataDef.getArtifactLabel());
-		ArtifactDefinition artifactDef = new ArtifactDefinition(artifactDataDef, "UEsDBAoAAAAIAAeLb0bDQz");
-		op.setImplementation(artifactDef);
-	}
+    private void addImplementationToOperation(Operation op) {
+        ArtifactDataDefinition artifactDataDef = new ArtifactDataDefinition();
+        artifactDataDef.setArtifactChecksum("YTg2Mjg4MWJhNmI5NzBiNzdDFkMWI=");
+        artifactDataDef.setArtifactName("create_myRoot.sh");
+        artifactDataDef.setArtifactLabel("create_myRoot");
+        artifactDataDef.setArtifactType("SHELL");
+        artifactDataDef.setDescription("good description");
+        artifactDataDef.setEsId("esId");
+        artifactDataDef.setUniqueId(op.getUniqueId() + "." + artifactDataDef.getArtifactLabel());
+        ArtifactDefinition artifactDef = new ArtifactDefinition(artifactDataDef, "UEsDBAoAAAAIAAeLb0bDQz");
+        op.setImplementation(artifactDef);
+    }
 
-	private InterfaceDefinition buildInterfaceDefinition() {
-		InterfaceDefinition interfaceDefinition = new InterfaceDefinition();
-		interfaceDefinition.setType("tosca.interfaces.standard");
-		interfaceDefinition.setCreationDate(new Long(101232));
+    private InterfaceDefinition buildInterfaceDefinition() {
+        InterfaceDefinition interfaceDefinition = new InterfaceDefinition();
+        interfaceDefinition.setType("tosca.interfaces.standard");
+        interfaceDefinition.setCreationDate(new Long(101232));
 
-		return interfaceDefinition;
-	}
+        return interfaceDefinition;
+    }
 
-	private Operation buildOperationDefinition() {
-		Operation op = new Operation();
-		op.setCreationDate(new Long(101232));
-		op.setDescription("asda");
+    private Operation buildOperationDefinition() {
+        Operation op = new Operation();
+        op.setCreationDate(new Long(101232));
+        op.setDescription("asda");
 
-		return op;
-	}
+        return op;
+    }
 
-	private void deleteAndCreateCategory(String category) {
-		String[] names = category.split("/");
-		OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao);
+    private void deleteAndCreateCategory(String category) {
+        String[] names = category.split("/");
+        OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao);
 
-		/*
-		 * CategoryData categoryData = new CategoryData(); categoryData.setName(category);
-		 * 
-		 * titanDao.deleteNode(categoryData, CategoryData.class); Either<CategoryData, TitanOperationStatus> createNode = titanDao .createNode(categoryData, CategoryData.class); System.out.println("after creating caetgory " + createNode);
-		 */
+        /*
+         * CategoryData categoryData = new CategoryData(); categoryData.setName(category);
+         *
+         * titanDao.deleteNode(categoryData, CategoryData.class); Either<CategoryData, TitanOperationStatus> createNode = titanDao .createNode(categoryData, CategoryData.class); System.out.println("after creating caetgory " + createNode);
+         */
 
-	}
+    }
 
-	private UserData deleteAndCreateUser(String userId, String firstName, String lastName) {
-		UserData userData = new UserData();
-		userData.setUserId(userId);
-		userData.setFirstName(firstName);
-		userData.setLastName(lastName);
+    private UserData deleteAndCreateUser(String userId, String firstName, String lastName) {
+        UserData userData = new UserData();
+        userData.setUserId(userId);
+        userData.setFirstName(firstName);
+        userData.setLastName(lastName);
 
-		titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class);
-		titanDao.createNode(userData, UserData.class);
-		titanDao.commit();
+        titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class);
+        titanDao.createNode(userData, UserData.class);
+        titanDao.commit();
 
-		return userData;
-	}
+        return userData;
+    }
 
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperationTest.java
index 3551555..64856c8 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperationTest.java
@@ -20,16 +20,9 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import static com.google.common.collect.Sets.newHashSet;
-import static java.util.Arrays.asList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.stream.Stream;
-
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.junit.Before;
@@ -45,153 +38,155 @@
 import org.openecomp.sdc.be.model.ModelTestBase;
 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.operations.StorageException;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.resources.data.PolicyTypeData;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.thinkaurelius.titan.core.TitanVertex;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Stream;
 
-import fj.data.Either;
+import static com.google.common.collect.Sets.newHashSet;
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:application-context-test.xml")
 public class PolicyTypeOperationTest extends ModelTestBase {
 
-	private static final String NULL_STRING = null;
-	@Autowired
-	private PolicyTypeOperation policyTypeOperation;
+    private static final String NULL_STRING = null;
+    @Autowired
+    private PolicyTypeOperation policyTypeOperation;
 
-	@Autowired
-	private TitanGenericDao titanGenericDao;
+    @Autowired
+    private TitanGenericDao titanGenericDao;
 
-	@BeforeClass
-	public static void setupBeforeClass() {
-		ModelTestBase.init();
+    @BeforeClass
+    public static void setupBeforeClass() {
+        ModelTestBase.init();
 
-	}
+    }
 
-	@Before
-	public void cleanUp() {
-		TitanGenericDao titanGenericDao = policyTypeOperation.titanGenericDao;
-		Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph();
-		TitanGraph graph = graphResult.left().value();
+    @Before
+    public void cleanUp() {
+        TitanGenericDao titanGenericDao = policyTypeOperation.titanGenericDao;
+        Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph();
+        TitanGraph graph = graphResult.left().value();
 
-		Iterable<TitanVertex> vertices = graph.query().vertices();
-		if (vertices != null) {
-			Iterator<TitanVertex> iterator = vertices.iterator();
-			while (iterator.hasNext()) {
-				TitanVertex vertex = iterator.next();
-				vertex.remove();
-			}
+        Iterable<TitanVertex> vertices = graph.query().vertices();
+        if (vertices != null) {
+            Iterator<TitanVertex> iterator = vertices.iterator();
+            while (iterator.hasNext()) {
+                TitanVertex vertex = iterator.next();
+                vertex.remove();
+            }
 
-		}
-		titanGenericDao.commit();
-	}
+        }
+        titanGenericDao.commit();
+    }
 
-	@Test
-	public void testAddPolicyType() {
+    @Test
+    public void testAddPolicyType() {
+        PolicyTypeDefinition policyTypePreCreate = createPolicyTypeDef();
+        assertTrue(StringUtils.isEmpty(policyTypePreCreate.getUniqueId()));
+        Either<PolicyTypeDefinition, StorageOperationStatus> addPolicyType = policyTypeOperation.addPolicyType(policyTypePreCreate);
+        assertTrue(addPolicyType.isLeft());
+        PolicyTypeDefinition policyTypePostCreate = addPolicyType.left().value();
+        assertThat(policyTypePostCreate.getUniqueId()).isNotEmpty();
+        assertThat(policyTypePostCreate)
+                .isEqualToComparingOnlyGivenFields(policyTypePreCreate, "name", "icon", "description", "type");
+    }
 
-		PolicyTypeDefinition policyTypePreCreate = createPolicyTypeDef();
-		assertTrue(StringUtils.isEmpty(policyTypePreCreate.getUniqueId()));
-		Either<PolicyTypeDefinition, StorageOperationStatus> addPolicyType = policyTypeOperation.addPolicyType(policyTypePreCreate);
-		assertTrue(addPolicyType.isLeft());
-		PolicyTypeDefinition policyTypePostCreate = addPolicyType.left().value();
-		assertEquals(policyTypePostCreate.getType(), policyTypePreCreate.getType());
-		assertEquals(policyTypePostCreate.getDescription(), policyTypePreCreate.getDescription());
+    @Test
+    public void testGetLatestPolicyTypeByType() {
+        PolicyTypeDefinition policyTypeCreated = policyTypeOperation.addPolicyType(createPolicyTypeDef()).left().value();
+        Either<PolicyTypeDefinition, StorageOperationStatus> eitherPolicyTypeFetched = policyTypeOperation.getLatestPolicyTypeByType(policyTypeCreated.getType());
+        assertTrue(eitherPolicyTypeFetched.isLeft());
+        PolicyTypeDefinition policyTypeFetched = eitherPolicyTypeFetched.left().value();
+        assertEquals(policyTypeFetched.toString(), policyTypeCreated.toString());
+    }
 
-		assertTrue(!StringUtils.isEmpty(policyTypePostCreate.getUniqueId()));
-	}
+    @Test
+    public void testGetLatestPolicyTypeByType_derivedFromFetchedCorrectly() {
+        PolicyTypeDefinition rootPolicyType = createRootPolicyTypeOnGraph();
+        String derivedFromRootType = rootPolicyType.getType();
+        PolicyTypeDefinition policyType1 = createPolicyTypeDef("tosca.policies.type1", "desc1", derivedFromRootType);
+        policyTypeOperation.addPolicyType(policyType1);
+        Either<PolicyTypeDefinition, StorageOperationStatus> eitherPolicyTypeFetched = policyTypeOperation.getLatestPolicyTypeByType(policyType1.getType());
+        assertThat(eitherPolicyTypeFetched.left().value().getDerivedFrom()).isEqualTo(rootPolicyType.getType());
+    }
 
-	@Test
-	public void testGetLatestPolicyTypeByType() {
-		PolicyTypeDefinition policyTypeCreated = policyTypeOperation.addPolicyType(createPolicyTypeDef()).left().value();
-		Either<PolicyTypeDefinition, StorageOperationStatus> eitherPolicyTypeFetched = policyTypeOperation.getLatestPolicyTypeByType(policyTypeCreated.getType());
-		assertTrue(eitherPolicyTypeFetched.isLeft());
-		PolicyTypeDefinition policyTypeFetched = eitherPolicyTypeFetched.left().value();
-		assertEquals(policyTypeFetched.toString(), policyTypeCreated.toString());
-	}
+    @Test
+    public void testGetLatestPolicyTypeByType_whenGettingTypeGetPropertiesFromAllDerivedFromChain_policyTypeHasNoDirectProps() {
+        PropertyDefinition prop1 = createSimpleProperty("val1", "prop1", "string");
+        PropertyDefinition prop2 = createSimpleProperty("val2", "prop2", "string");
+        PolicyTypeDefinition policyType1 = createPolicyTypeDef("tosca.policies.type1", null, prop1, prop2);
+        PolicyTypeDefinition policyType2 = createPolicyTypeDef("tosca.policies.type2", "desc3", policyType1.getType(), null);
+        addPolicyTypesToDB(policyType1, policyType2);
+        Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyType2 = policyTypeOperation.getLatestPolicyTypeByType(policyType2.getType());
+        assertThat(latestPolicyType2.isLeft()).isTrue();
+        assertThat(latestPolicyType2.left().value().getProperties())
+                .usingElementComparatorOnFields("defaultValue", "name", "type")
+                .containsExactlyInAnyOrder(prop1, prop2);
+    }
 
-	@Test
-	public void testGetLatestPolicyTypeByType_derivedFromFetchedCorrectly() {
-		PolicyTypeDefinition rootPolicyType = createRootPolicyTypeOnGraph();
-		String derivedFromRootType = rootPolicyType.getType();
-		PolicyTypeDefinition policyType1 = createPolicyTypeDef("tosca.policies.type1", "desc1", derivedFromRootType);
-		policyTypeOperation.addPolicyType(policyType1);
-		Either<PolicyTypeDefinition, StorageOperationStatus> eitherPolicyTypeFetched = policyTypeOperation.getLatestPolicyTypeByType(policyType1.getType());
-		assertThat(eitherPolicyTypeFetched.left().value().getDerivedFrom()).isEqualTo(rootPolicyType.getType());
-	}
+    @Test
+    public void testGetLatestPolicyTypeByType_whenGettingTypeGetPropertiesFromAllDerivedFromChain() {
+        PropertyDefinition prop1 = createSimpleProperty("val1", "prop1", "string");
+        PropertyDefinition prop2 = createSimpleProperty("val2", "prop2", "string");
+        PropertyDefinition prop3 = createSimpleProperty("val3", "prop3", "string");
 
-	@Test
-	public void testGetLatestPolicyTypeByType_whenGettingTypeGetPropertiesFromAllDerivedFromChain_policyTypeHasNoDirectProps() {
-		PropertyDefinition prop1 = createSimpleProperty("val1", "prop1", "string");
-		PropertyDefinition prop2 = createSimpleProperty("val2", "prop2", "string");
-		PolicyTypeDefinition policyType1 = createPolicyTypeDef("tosca.policies.type1", null, prop1, prop2);
-		PolicyTypeDefinition policyType2 = createPolicyTypeDef("tosca.policies.type2", "desc3", policyType1.getType(), null);
-		addPolicyTypesToDB(policyType1, policyType2);
-		Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyType2 = policyTypeOperation.getLatestPolicyTypeByType(policyType2.getType());
-		assertThat(latestPolicyType2.isLeft());
-		assertThat(latestPolicyType2.left().value().getProperties())
-				.usingElementComparatorOnFields("defaultValue", "name", "type")
-				.containsExactlyInAnyOrder(prop1, prop2);
-	}
+        PolicyTypeDefinition rootPolicyType = createPolicyTypeDef(prop1);
+        PolicyTypeDefinition policyType1 = createPolicyTypeDef("tosca.policies.type1", "desc1", rootPolicyType.getType(), null);
+        PolicyTypeDefinition policyType2 = createPolicyTypeDef("tosca.policies.type2", "desc2", policyType1.getType(), prop2);
+        PolicyTypeDefinition policyType3 = createPolicyTypeDef("tosca.policies.type3", "desc3", policyType2.getType(), null);
+        PolicyTypeDefinition policyType4 = createPolicyTypeDef("tosca.policies.type4", "desc4", policyType3.getType(), prop3);
 
-	@Test
-	public void testGetLatestPolicyTypeByType_whenGettingTypeGetPropertiesFromAllDerivedFromChain() {
-		PropertyDefinition prop1 = createSimpleProperty("val1", "prop1", "string");
-		PropertyDefinition prop2 = createSimpleProperty("val2", "prop2", "string");
-		PropertyDefinition prop3 = createSimpleProperty("val3", "prop3", "string");
+        addPolicyTypesToDB(rootPolicyType, policyType1, policyType2, policyType3, policyType4);
 
-		PolicyTypeDefinition rootPolicyType = createPolicyTypeDef(prop1);
-		PolicyTypeDefinition policyType1 = createPolicyTypeDef("tosca.policies.type1", "desc1", rootPolicyType.getType(), null);
-		PolicyTypeDefinition policyType2 = createPolicyTypeDef("tosca.policies.type2", "desc2", policyType1.getType(), prop2);
-		PolicyTypeDefinition policyType3 = createPolicyTypeDef("tosca.policies.type3", "desc3", policyType2.getType(), null);
-		PolicyTypeDefinition policyType4 = createPolicyTypeDef("tosca.policies.type4", "desc4", policyType3.getType(), prop3);
+        Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyType3 = policyTypeOperation.getLatestPolicyTypeByType(policyType4.getType());
+        assertThat(latestPolicyType3.isLeft()).isTrue();
+        assertThat(latestPolicyType3.left().value().getProperties())
+                .usingElementComparatorOnFields("defaultValue", "name", "type")
+                .containsExactlyInAnyOrder(prop1, prop2, prop3);
+    }
 
-		addPolicyTypesToDB(rootPolicyType, policyType1, policyType2, policyType3, policyType4);
+    @Test(expected = StorageException.class)
+    public void getAllPolicyTypes_noPolicies() {
+        policyTypeOperation.getAllPolicyTypes(null);
+    }
 
-		Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyType3 = policyTypeOperation.getLatestPolicyTypeByType(policyType4.getType());
-		assertThat(latestPolicyType3.isLeft());
-		assertThat(latestPolicyType3.left().value().getProperties())
-				.usingElementComparatorOnFields("defaultValue", "name", "type")
-				.containsExactlyInAnyOrder(prop1, prop2, prop3);
-	}
+    @Test
+    public void getAllPolicyTypes() {
+        PolicyTypeDefinition policyType1 = createPolicyTypeDef();
+        PolicyTypeDefinition policyType2 = createPolicyTypeDef("tosca.policies.test1", "desc1", "tosca.policies.Root");
+        addPolicyTypesToDB(policyType1, policyType2);
+        List<PolicyTypeDefinition> allPolicyTypesWithNoExcluded = policyTypeOperation.getAllPolicyTypes(null);
+        assertThat(allPolicyTypesWithNoExcluded).hasSize(2);
+        assertThat(allPolicyTypesWithNoExcluded).usingElementComparatorOnFields("uniqueId", "description", "version", "type")
+                .containsExactlyInAnyOrder(policyType1, policyType2);
+    }
 
-	@Test
-	public void getAllPolicyTypes_noPolicies() {
-		Either<List<PolicyTypeDefinition>, StorageOperationStatus> allPolicyTypes = policyTypeOperation.getAllPolicyTypes(null);
-		assertThat(allPolicyTypes.isRight());
-		assertThat(allPolicyTypes.right().value()).isEqualTo(StorageOperationStatus.NOT_FOUND);
-	}
+    @Test
+    public void getAllPolicyTypes_whenPassingExcludedTypeList_dontReturnExcludedTypes() {
+        PolicyTypeDefinition policyType1 = createPolicyTypeDef();
+        PolicyTypeDefinition policyType2 = createPolicyTypeDef("tosca.policies.test1", "desc1", "tosca.policies.Root");
+        PolicyTypeDefinition policyType3 = createPolicyTypeDef("tosca.policies.test2", "desc2", "tosca.policies.Root");
+        policyTypeOperation.addPolicyType(policyType1);
+        policyTypeOperation.addPolicyType(policyType2);
+        policyTypeOperation.addPolicyType(policyType3);
+        List<PolicyTypeDefinition> allPolicyTypes = policyTypeOperation.getAllPolicyTypes(newHashSet("tosca.policies.test1", "tosca.policies.test2"));
+        assertThat(allPolicyTypes).hasSize(1);
+        assertThat(allPolicyTypes).usingElementComparatorOnFields("type")
+                                                 .containsExactly(policyType1);
+    }
 
-	@Test
-	public void getAllPolicyTypes() {
-		PolicyTypeDefinition policyType1 = createPolicyTypeDef();
-		PolicyTypeDefinition policyType2 = createPolicyTypeDef("tosca.policies.test1", "desc1", "tosca.policies.Root");
-		addPolicyTypesToDB(policyType1, policyType2);
-		Either<List<PolicyTypeDefinition>, StorageOperationStatus> allPolicyTypesWithNoExcluded = policyTypeOperation.getAllPolicyTypes(null);
-		assertThat(allPolicyTypesWithNoExcluded.left().value()).hasSize(2);
-		assertThat(allPolicyTypesWithNoExcluded.left().value()).usingElementComparatorOnFields("uniqueId", "description", "version", "type")
-				.containsExactlyInAnyOrder(policyType1, policyType2);
-	}
-
-	@Test
-	public void getAllPolicyTypes_whenPassingExcludedTypeList_dontReturnExcludedTypes() {
-		PolicyTypeDefinition policyType1 = createPolicyTypeDef();
-		PolicyTypeDefinition policyType2 = createPolicyTypeDef("tosca.policies.test1", "desc1", "tosca.policies.Root");
-		PolicyTypeDefinition policyType3 = createPolicyTypeDef("tosca.policies.test2", "desc2", "tosca.policies.Root");
-		policyTypeOperation.addPolicyType(policyType1);
-		policyTypeOperation.addPolicyType(policyType2);
-		policyTypeOperation.addPolicyType(policyType3);
-		Either<List<PolicyTypeDefinition>, StorageOperationStatus> allPolicyTypes = policyTypeOperation.getAllPolicyTypes(newHashSet("tosca.policies.test1", "tosca.policies.test2"));
-		assertThat(allPolicyTypes.left().value()).hasSize(1);
-		assertThat(allPolicyTypes.left().value()).usingElementComparatorOnFields("type")
-												 .containsExactly(policyType1);
-	}
-
-	@Test
+    @Test
     public void addPolicyType_whenDerivedFromNodeNotExist_returnNotFound() {
         PolicyTypeDefinition type1 = createPolicyTypeDef("tosca.policies.type1", "desc1", "derivedFrom");
         Either<PolicyTypeDefinition, StorageOperationStatus> addedPolicyTypeResult = policyTypeOperation.addPolicyType(type1);
@@ -199,7 +194,7 @@
     }
 
     @Test//bug379696
-	public void addPolicyType_derivedFromAddedCorrectly() {
+    public void addPolicyType_derivedFromAddedCorrectly() {
         PolicyTypeDefinition rootPolicyType = createRootPolicyTypeOnGraph();
         String derivedFromRootType = rootPolicyType.getType();
         PolicyTypeDefinition policyType1 = createPolicyTypeDef("tosca.policies.type1", "desc1", derivedFromRootType);
@@ -207,174 +202,171 @@
         assertThat(addedPolicyTypeResult.isLeft()).isTrue();
 
         Either<PolicyTypeDefinition, StorageOperationStatus> fetchedPolicyType = policyTypeOperation.getLatestPolicyTypeByType(policyType1.getType());
-		PolicyTypeDefinition fetchedPolicyTypeVal = fetchedPolicyType.left().value();
-		assertThat(fetchedPolicyTypeVal.getDerivedFrom()).isEqualTo(derivedFromRootType);
-		verifyDerivedFromNodeEqualsToRootPolicyType(rootPolicyType, fetchedPolicyTypeVal.getUniqueId());
+        PolicyTypeDefinition fetchedPolicyTypeVal = fetchedPolicyType.left().value();
+        assertThat(fetchedPolicyTypeVal.getDerivedFrom()).isEqualTo(derivedFromRootType);
+        verifyDerivedFromNodeEqualsToRootPolicyType(rootPolicyType, fetchedPolicyTypeVal.getUniqueId());
 
-	}
+    }
 
-	@Test
-	public void updatePolicyType_returnNotFoundErrorIfTryingToUpdateANonExistingType() {
-		PolicyTypeDefinition currType = createPolicyTypeDef();
-		PolicyTypeDefinition updatedType = createPolicyTypeDef();
-		Either<PolicyTypeDefinition, StorageOperationStatus> updatePolicyTypeRes = policyTypeOperation.updatePolicyType(updatedType, currType);
-		assertThat(updatePolicyTypeRes.right().value()).isEqualTo(StorageOperationStatus.NOT_FOUND);
-	}
+    @Test
+    public void updatePolicyType_returnNotFoundErrorIfTryingToUpdateANonExistingType() {
+        PolicyTypeDefinition currType = createPolicyTypeDef();
+        PolicyTypeDefinition updatedType = createPolicyTypeDef();
+        Either<PolicyTypeDefinition, StorageOperationStatus> updatePolicyTypeRes = policyTypeOperation.updatePolicyType(updatedType, currType);
+        assertThat(updatePolicyTypeRes.right().value()).isEqualTo(StorageOperationStatus.NOT_FOUND);
+    }
 
-	@Test
-	public void updatePolicyType_basicFields() {
-		PolicyTypeDefinition createdType = createPolicyTypeDef("type1", "description1", NULL_STRING);
-		Either<PolicyTypeDefinition, StorageOperationStatus> currPolicyType = policyTypeOperation.addPolicyType(createdType);
+    @Test
+    public void updatePolicyType_basicFields() {
+        PolicyTypeDefinition createdType = createPolicyTypeDef("type1", "description1", NULL_STRING);
+        Either<PolicyTypeDefinition, StorageOperationStatus> currPolicyType = policyTypeOperation.addPolicyType(createdType);
 
-		PolicyTypeDefinition updatedType = createPolicyTypeDef("type1", "description2", NULL_STRING);
-		policyTypeOperation.updatePolicyType(updatedType, currPolicyType.left().value());
+        PolicyTypeDefinition updatedType = createPolicyTypeDef("type1", "description2", NULL_STRING);
+        updatedType.setName("newName");
+        updatedType.setIcon("icon");
+        policyTypeOperation.updatePolicyType(updatedType, currPolicyType.left().value());
 
-		Either<PolicyTypeDefinition, StorageOperationStatus> fetchedUpdatedType = policyTypeOperation.getLatestPolicyTypeByType(createdType.getType());
-		PolicyTypeDefinition fetchedPolicyType = fetchedUpdatedType.left().value();
-		assertThat(fetchedPolicyType.getProperties()).isEmpty();
-		assertThat(fetchedPolicyType)
-				.isEqualToIgnoringGivenFields(updatedType, "properties");
+        Either<PolicyTypeDefinition, StorageOperationStatus> fetchedUpdatedType = policyTypeOperation.getLatestPolicyTypeByType(createdType.getType());
+        PolicyTypeDefinition fetchedPolicyType = fetchedUpdatedType.left().value();
+        assertThat(fetchedPolicyType.getProperties()).isEmpty();
+        assertThat(fetchedPolicyType)
+                .isEqualToIgnoringGivenFields(updatedType, "properties");
 
-	}
+    }
 
-	@Test
-	public void updatePolicyType_updateProperties() {
-		PropertyDefinition prop1 = createSimpleProperty("val1", "prop1", "string");
-		PolicyTypeDefinition policyType = createPolicyTypeDef(prop1);
-		Either<PolicyTypeDefinition, StorageOperationStatus> currPolicyType = policyTypeOperation.addPolicyType(policyType);
+    @Test
+    public void updatePolicyType_updateProperties() {
+        PropertyDefinition prop1 = createSimpleProperty("val1", "prop1", "string");
+        PropertyDefinition prop2 = createSimpleProperty("val2", "prop2", "string");
+        PolicyTypeDefinition policyType = createPolicyTypeDef(prop1);
+        Either<PolicyTypeDefinition, StorageOperationStatus> currPolicyType = policyTypeOperation.addPolicyType(policyType);
 
-		PropertyDefinition updatedProp1 = duplicateProperty(prop1, "newVal1", "int");
-		PropertyDefinition prop2 = createSimpleProperty("val2", "prop2", "string");
-		PolicyTypeDefinition updatedPolicyType = createPolicyTypeDef(updatedProp1, prop2);
+        PropertyDefinition updatedProp1 = duplicateProperty(prop1, "newVal1", "int");
+        PropertyDefinition prop3 = createSimpleProperty("val3", "prop3", "string");
+        PolicyTypeDefinition updatedPolicyType = createPolicyTypeDef(updatedProp1, prop3);
 
-		policyTypeOperation.updatePolicyType(updatedPolicyType, currPolicyType.left().value());
+        policyTypeOperation.updatePolicyType(updatedPolicyType, currPolicyType.left().value());
 
-		Either<PolicyTypeDefinition, StorageOperationStatus> fetchedUpdatedType = policyTypeOperation.getLatestPolicyTypeByType(policyType.getType());
-		assertThat(fetchedUpdatedType.left().value().getProperties())
-				.usingElementComparatorOnFields("name", "defaultValue", "type")
-				.containsExactlyInAnyOrder(updatedProp1, prop2);
+        Either<PolicyTypeDefinition, StorageOperationStatus> fetchedUpdatedType = policyTypeOperation.getLatestPolicyTypeByType(policyType.getType());
+        assertThat(fetchedUpdatedType.left().value().getProperties())
+                .usingElementComparatorOnFields("name", "defaultValue", "type")
+                .containsExactlyInAnyOrder(updatedProp1, prop3);
 
-	}
+    }
 
-	@Test
-	public void updatePolicyType_derivedFrom_whenNoPrevDerivedFrom_updateToNewDerivedFrom() {
-		PolicyTypeDefinition rootPolicyType = createPolicyTypeDef();
-		PolicyTypeDefinition policyType1 = createPolicyTypeDef("type1", "descr", NULL_STRING);
-		PolicyTypeDefinition updatedPolicyType = createPolicyTypeDef("type1", "descr", rootPolicyType.getType());
-		policyTypeOperation.addPolicyType(rootPolicyType);
-		Either<PolicyTypeDefinition, StorageOperationStatus> currPolicyType = policyTypeOperation.addPolicyType(policyType1);
-		policyTypeOperation.updatePolicyType(updatedPolicyType, currPolicyType.left().value());
+    @Test
+    public void updatePolicyType_derivedFrom_whenNoPrevDerivedFrom_updateToNewDerivedFrom() {
+        PolicyTypeDefinition rootPolicyType = createPolicyTypeDef();
+        PolicyTypeDefinition policyType1 = createPolicyTypeDef("type1", "descr", NULL_STRING);
+        PolicyTypeDefinition updatedPolicyType = createPolicyTypeDef("type1", "descr", rootPolicyType.getType());
+        policyTypeOperation.addPolicyType(rootPolicyType);
+        Either<PolicyTypeDefinition, StorageOperationStatus> currPolicyType = policyTypeOperation.addPolicyType(policyType1);
+        policyTypeOperation.updatePolicyType(updatedPolicyType, currPolicyType.left().value());
 
-		Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyType = policyTypeOperation.getLatestPolicyTypeByType(policyType1.getType());
-		assertThat(latestPolicyType.left().value().getDerivedFrom()).isEqualTo(rootPolicyType.getType());
-		verifyDerivedFromNodeEqualsToRootPolicyType(rootPolicyType, latestPolicyType.left().value().getUniqueId());
-	}
+        Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyType = policyTypeOperation.getLatestPolicyTypeByType(policyType1.getType());
+        assertThat(latestPolicyType.left().value().getDerivedFrom()).isEqualTo(rootPolicyType.getType());
+        verifyDerivedFromNodeEqualsToRootPolicyType(rootPolicyType, latestPolicyType.left().value().getUniqueId());
+    }
 
-	@Test
-	public void updatePolicyType_derivedFrom_updateToNullDerivedFrom_derivedFromDeleted() {
-		PolicyTypeDefinition rootPolicyType = createPolicyTypeDef();
-		PolicyTypeDefinition policyType1 = createPolicyTypeDef("type1", "descr", rootPolicyType.getType());
-		PolicyTypeDefinition updatedPolicyType = createPolicyTypeDef("type1", "descr", null, new PropertyDefinition[]{});
-		policyTypeOperation.addPolicyType(rootPolicyType);
-		Either<PolicyTypeDefinition, StorageOperationStatus> currPolicyType = policyTypeOperation.addPolicyType(policyType1);
+    @Test
+    public void updatePolicyType_derivedFrom_updateToNullDerivedFrom_derivedFromDeleted() {
+        PolicyTypeDefinition rootPolicyType = createPolicyTypeDef();
+        PolicyTypeDefinition policyType1 = createPolicyTypeDef("type1", "descr", rootPolicyType.getType());
+        PolicyTypeDefinition updatedPolicyType = createPolicyTypeDef("type1", "descr", null, new PropertyDefinition[]{});
+        policyTypeOperation.addPolicyType(rootPolicyType);
+        Either<PolicyTypeDefinition, StorageOperationStatus> currPolicyType = policyTypeOperation.addPolicyType(policyType1);
 
-		policyTypeOperation.updatePolicyType(updatedPolicyType, currPolicyType.left().value());
+        policyTypeOperation.updatePolicyType(updatedPolicyType, currPolicyType.left().value());
 
-		Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyType = policyTypeOperation.getLatestPolicyTypeByType(policyType1.getType());
-		assertThat(latestPolicyType.left().value().getDerivedFrom()).isNull();
-		verifyDerivedFromRelationDoesntExist(latestPolicyType.left().value().getUniqueId());
-	}
+        Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyType = policyTypeOperation.getLatestPolicyTypeByType(policyType1.getType());
+        assertThat(latestPolicyType.left().value().getDerivedFrom()).isNull();
+        verifyDerivedFromRelationDoesntExist(latestPolicyType.left().value().getUniqueId());
+    }
 
-	@Test
-	public void updatePolicyType_updateDerivedFrom() {
-		PolicyTypeDefinition rootPolicyType = createPolicyTypeDef();
-		PolicyTypeDefinition derivedType1 = createPolicyTypeDef("derivedType1", "descr", NULL_STRING);
-		PolicyTypeDefinition policyType1 = createPolicyTypeDef("type1", "descr", derivedType1.getType());
-		PolicyTypeDefinition updatedPolicyType = createPolicyTypeDef("type1", "descr", rootPolicyType.getType());
+    @Test
+    public void updatePolicyType_updateDerivedFrom() {
+        PolicyTypeDefinition rootPolicyType = createPolicyTypeDef();
+        PolicyTypeDefinition derivedType1 = createPolicyTypeDef("derivedType1", "descr", NULL_STRING);
+        PolicyTypeDefinition policyType1 = createPolicyTypeDef("type1", "descr", derivedType1.getType());
+        PolicyTypeDefinition updatedPolicyType = createPolicyTypeDef("type1", "descr", rootPolicyType.getType());
 
-		policyTypeOperation.addPolicyType(rootPolicyType);
-		policyTypeOperation.addPolicyType(derivedType1);
-		Either<PolicyTypeDefinition, StorageOperationStatus> currPolicyType = policyTypeOperation.addPolicyType(policyType1);
+        policyTypeOperation.addPolicyType(rootPolicyType);
+        policyTypeOperation.addPolicyType(derivedType1);
+        Either<PolicyTypeDefinition, StorageOperationStatus> currPolicyType = policyTypeOperation.addPolicyType(policyType1);
 
-		policyTypeOperation.updatePolicyType(updatedPolicyType, currPolicyType.left().value());
+        policyTypeOperation.updatePolicyType(updatedPolicyType, currPolicyType.left().value());
 
-		Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyType = policyTypeOperation.getLatestPolicyTypeByType(policyType1.getType());
-		assertThat(latestPolicyType.left().value().getDerivedFrom()).isEqualTo(rootPolicyType.getType());
-		verifyDerivedFromNodeEqualsToRootPolicyType(rootPolicyType, latestPolicyType.left().value().getUniqueId());
-	}
+        Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyType = policyTypeOperation.getLatestPolicyTypeByType(policyType1.getType());
+        assertThat(latestPolicyType.left().value().getDerivedFrom()).isEqualTo(rootPolicyType.getType());
+        verifyDerivedFromNodeEqualsToRootPolicyType(rootPolicyType, latestPolicyType.left().value().getUniqueId());
+    }
 
-	private PropertyDefinition duplicateProperty(PropertyDefinition prop1, String updatedValue, String updatedType) {
-		PropertyDefinition updatedProp1 = new PropertyDefinition(prop1);
-		updatedProp1.setUniqueId(null);
-		updatedProp1.setDefaultValue(updatedValue);
-		updatedProp1.setType(updatedType);
-		return updatedProp1;
-	}
+    private PropertyDefinition duplicateProperty(PropertyDefinition prop1, String updatedValue, String updatedType) {
+        PropertyDefinition updatedProp1 = new PropertyDefinition(prop1);
+        updatedProp1.setUniqueId(null);
+        updatedProp1.setDefaultValue(updatedValue);
+        updatedProp1.setType(updatedType);
+        return updatedProp1;
+    }
 
-	private PropertyDefinition createSimpleProperty(String defaultValue, String name, String type) {
-		PropertyDefinition prop1 = new PropertyDefinition();
-		prop1.setDefaultValue(defaultValue);
-		prop1.setName(name);
-		prop1.setType(type);
-		return prop1;
-	}
+    private void verifyDerivedFromNodeEqualsToRootPolicyType(PolicyTypeDefinition rootPolicyType, String parentPolicyId) {
+        Either<ImmutablePair<PolicyTypeData, GraphEdge>, TitanOperationStatus> derivedFromRelation = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PolicyType), parentPolicyId, GraphEdgeLabels.DERIVED_FROM,
+                NodeTypeEnum.PolicyType, PolicyTypeData.class);
+        assertThat(derivedFromRelation.left().value().getLeft().getPolicyTypeDataDefinition())
+                .isEqualToComparingFieldByField(rootPolicyType);
+    }
 
-	private void verifyDerivedFromNodeEqualsToRootPolicyType(PolicyTypeDefinition rootPolicyType, String parentPolicyId) {
-		Either<ImmutablePair<PolicyTypeData, GraphEdge>, TitanOperationStatus> derivedFromRelation = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PolicyType), parentPolicyId, GraphEdgeLabels.DERIVED_FROM,
-				NodeTypeEnum.PolicyType, PolicyTypeData.class);
-		assertThat(derivedFromRelation.left().value().getLeft().getPolicyTypeDataDefinition())
-				.isEqualToComparingFieldByField(rootPolicyType);
-	}
+    private void verifyDerivedFromRelationDoesntExist(String parentPolicyId) {
+        Either<ImmutablePair<PolicyTypeData, GraphEdge>, TitanOperationStatus> derivedFromRelation = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PolicyType), parentPolicyId, GraphEdgeLabels.DERIVED_FROM,
+                NodeTypeEnum.PolicyType, PolicyTypeData.class);
+        assertThat(derivedFromRelation.right().value())
+                .isEqualTo(TitanOperationStatus.NOT_FOUND);
+    }
 
-	private void verifyDerivedFromRelationDoesntExist(String parentPolicyId) {
-		Either<ImmutablePair<PolicyTypeData, GraphEdge>, TitanOperationStatus> derivedFromRelation = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PolicyType), parentPolicyId, GraphEdgeLabels.DERIVED_FROM,
-				NodeTypeEnum.PolicyType, PolicyTypeData.class);
-		assertThat(derivedFromRelation.right().value())
-				.isEqualTo(TitanOperationStatus.NOT_FOUND);
-	}
-
-	private PolicyTypeDefinition createRootPolicyTypeOnGraph() {
+    private PolicyTypeDefinition createRootPolicyTypeOnGraph() {
         PolicyTypeDefinition rootPolicyType = createPolicyTypeDef();
         policyTypeOperation.addPolicyType(rootPolicyType);
         return rootPolicyType;
 
     }
 
-	private PolicyTypeDefinition createPolicyTypeDef() {
-		return createPolicyTypeDef("tosca.policies.Root", "description: The TOSCA Policy Type all other TOSCA Policy Types derive from", null, new PropertyDefinition[]{});
-	}
+    private PolicyTypeDefinition createPolicyTypeDef() {
+        return createPolicyTypeDef("tosca.policies.Root", "description: The TOSCA Policy Type all other TOSCA Policy Types derive from", null, new PropertyDefinition[]{});
+    }
 
-	private PolicyTypeDefinition createPolicyTypeDef(PropertyDefinition ... props) {
-		return createPolicyTypeDef("tosca.policies.Root",  null, props);
-	}
+    private PolicyTypeDefinition createPolicyTypeDef(PropertyDefinition ... props) {
+        return createPolicyTypeDef("tosca.policies.Root",  null, props);
+    }
 
-	private PolicyTypeDefinition createPolicyTypeDef(String type, String derivedFrom, PropertyDefinition ... props) {
-		PolicyTypeDefinition policyType = createPolicyTypeDef(type, "description: The TOSCA Policy Type all other TOSCA Policy Types derive from", derivedFrom);
-		policyType.setProperties(asList(props));
-		return policyType;
-	}
+    private PolicyTypeDefinition createPolicyTypeDef(String type, String derivedFrom, PropertyDefinition ... props) {
+        PolicyTypeDefinition policyType = createPolicyTypeDef(type, "description: The TOSCA Policy Type all other TOSCA Policy Types derive from", derivedFrom);
+        policyType.setProperties(asList(props));
+        return policyType;
+    }
 
-	private PolicyTypeDefinition createPolicyTypeDef(String type, String description, String derivedFrom) {
-		return createPolicyTypeDef(type, description, derivedFrom, null);
-	}
+    private PolicyTypeDefinition createPolicyTypeDef(String type, String description, String derivedFrom) {
+        return createPolicyTypeDef(type, description, derivedFrom, null);
+    }
 
-	private PolicyTypeDefinition createPolicyTypeDef(String type, String description, String derivedFrom,  PropertyDefinition ... props) {
-		PolicyTypeDataDefinition policyTypeDataDefinition = new PolicyTypeDataDefinition();
-		policyTypeDataDefinition.setDescription(description);
-		policyTypeDataDefinition.setType(type);
-		policyTypeDataDefinition.setDerivedFrom(derivedFrom);
-		PolicyTypeDefinition policyTypeDefinition = new PolicyTypeDefinition(policyTypeDataDefinition);
-		policyTypeDefinition.setHighestVersion(true);
-		policyTypeDefinition.setVersion("1.0");
-		if (props != null) {
-			policyTypeDefinition.setProperties(asList(props));
-		}
-		return policyTypeDefinition;
-	}
+    private PolicyTypeDefinition createPolicyTypeDef(String type, String description, String derivedFrom,  PropertyDefinition ... props) {
+        PolicyTypeDataDefinition policyTypeDataDefinition = new PolicyTypeDataDefinition();
+        policyTypeDataDefinition.setDescription(description);
+        policyTypeDataDefinition.setType(type);
+        policyTypeDataDefinition.setName(type + "name");
+        policyTypeDataDefinition.setIcon(type + "icon");
+        policyTypeDataDefinition.setDerivedFrom(derivedFrom);
+        PolicyTypeDefinition policyTypeDefinition = new PolicyTypeDefinition(policyTypeDataDefinition);
+        policyTypeDefinition.setHighestVersion(true);
+        policyTypeDefinition.setVersion("1.0");
+        if (props != null) {
+            policyTypeDefinition.setProperties(asList(props));
+        }
+        return policyTypeDefinition;
+    }
 
-	private void addPolicyTypesToDB(PolicyTypeDefinition ... policyTypeDefinitions) {
-		Stream.of(policyTypeDefinitions).forEach(policyTypeOperation::addPolicyType);
-	}
+    private void addPolicyTypesToDB(PolicyTypeDefinition ... policyTypeDefinitions) {
+        Stream.of(policyTypeDefinitions).forEach(policyTypeOperation::addPolicyType);
+    }
 
 
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperationTest.java
index 612dd7b..17d0586 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperationTest.java
@@ -20,19 +20,8 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import com.thinkaurelius.titan.core.TitanVertex;
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.junit.Assert;
 import org.junit.Before;
@@ -44,12 +33,7 @@
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.IComplexDefaultValue;
-import org.openecomp.sdc.be.model.ModelTestBase;
-import org.openecomp.sdc.be.model.PropertyConstraint;
-import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
 import org.openecomp.sdc.be.model.tosca.ToscaType;
@@ -60,490 +44,469 @@
 import org.openecomp.sdc.be.resources.data.PropertyData;
 import org.openecomp.sdc.be.resources.data.PropertyValueData;
 
-import com.thinkaurelius.titan.core.TitanVertex;
+import java.util.*;
 
-import fj.data.Either;
+import static org.junit.Assert.*;
 
 public class PropertyOperationTest extends ModelTestBase {
 
-	TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class);
+    TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class);
 
-	PropertyOperation propertyOperation = new PropertyOperation(titanGenericDao, null);
+    PropertyOperation propertyOperation = new PropertyOperation(titanGenericDao, null);
 
-	@Before
-	public void setup() {
-		propertyOperation.setTitanGenericDao(titanGenericDao);
+    @Before
+    public void setup() {
+        propertyOperation.setTitanGenericDao(titanGenericDao);
 
-	}
+    }
 
-	/*
-	 * @Test public void addPropertyToResourceTest() {
-	 * 
-	 * String propName = "myProp"; PropertyDefinition property =
-	 * buildPropertyDefinition(); List<PropertyConstraint> constraints =
-	 * buildConstraints(); property.setConstraints(constraints);
-	 * 
-	 * PropertyData propertyData = new PropertyData(property,
-	 * propertyOperation.convertConstraintsToString(constraints));
-	 * 
-	 * Either<PropertyData, TitanOperationStatus> either =
-	 * Either.left(propertyData);
-	 * //when(propertyDao.create((GraphNeighbourTable)anyObject(),
-	 * eq(PropertyData.class), eq(NodeTypeEnum.Property))).thenReturn(either);
-	 * GraphRelation graphRelation = new GraphRelation(); Either<GraphRelation,
-	 * TitanOperationStatus> relationResult = Either.left(graphRelation);
-	 * 
-	 * when(titanGenericDao.createNode((PropertyData)anyObject(),
-	 * eq(PropertyData.class))).thenReturn(either);
-	 * when(titanGenericDao.createRelation((GraphNode)anyObject(),
-	 * (GraphNode)anyObject(), eq(GraphEdgeLabels.PROPERTY),
-	 * anyMap())).thenReturn(relationResult);
-	 * 
-	 * Either<PropertyDefinition, StorageOperationStatus> result =
-	 * propertyOperation.addPropertyToResource(propName, property,
-	 * NodeTypeEnum.Resource, "my-resource.1.0");
-	 * 
-	 * assertTrue(result.isLeft()); System.out.println(result.left().value());
-	 * PropertyDefinition propertyDefinition = result.left().value();
-	 * 
-	 * List<PropertyConstraint> originalConstraints = property.getConstraints();
-	 * List<PropertyConstraint> propertyConstraintsResult =
-	 * propertyDefinition.getConstraints();
-	 * assertEquals(propertyConstraintsResult.size(),
-	 * originalConstraints.size());
-	 * 
-	 * }
-	 */
-	private PropertyDefinition buildPropertyDefinition() {
-		PropertyDefinition property = new PropertyDefinition();
-		property.setDefaultValue("10");
-		property.setDescription(
-				"Size of the local disk, in Gigabytes (GB), available to applications running on the Compute node.");
-		property.setType(ToscaType.INTEGER.name().toLowerCase());
-		return property;
-	}
+    /*
+     * @Test public void addPropertyToResourceTest() {
+     *
+     * String propName = "myProp"; PropertyDefinition property = buildPropertyDefinition(); List<PropertyConstraint> constraints = buildConstraints(); property.setConstraints(constraints);
+     *
+     * PropertyData propertyData = new PropertyData(property, propertyOperation.convertConstraintsToString(constraints));
+     *
+     * Either<PropertyData, TitanOperationStatus> either = Either.left(propertyData); //when(propertyDao.create((GraphNeighbourTable)anyObject(), eq(PropertyData.class), eq(NodeTypeEnum.Property))).thenReturn(either); GraphRelation graphRelation =
+     * new GraphRelation(); Either<GraphRelation, TitanOperationStatus> relationResult = Either.left(graphRelation);
+     *
+     * when(titanGenericDao.createNode((PropertyData)anyObject(), eq(PropertyData.class))).thenReturn(either); when(titanGenericDao.createRelation((GraphNode)anyObject(), (GraphNode)anyObject(), eq(GraphEdgeLabels.PROPERTY),
+     * anyMap())).thenReturn(relationResult);
+     *
+     * Either<PropertyDefinition, StorageOperationStatus> result = propertyOperation.addPropertyToResource(propName, property, NodeTypeEnum.Resource, "my-resource.1.0");
+     *
+     * assertTrue(result.isLeft()); System.out.println(result.left().value()); PropertyDefinition propertyDefinition = result.left().value();
+     *
+     * List<PropertyConstraint> originalConstraints = property.getConstraints(); List<PropertyConstraint> propertyConstraintsResult = propertyDefinition.getConstraints(); assertEquals(propertyConstraintsResult.size(), originalConstraints.size());
+     *
+     * }
+     */
+    private PropertyDefinition buildPropertyDefinition() {
+        PropertyDefinition property = new PropertyDefinition();
+        property.setDefaultValue("10");
+        property.setDescription("Size of the local disk, in Gigabytes (GB), available to applications running on the Compute node.");
+        property.setType(ToscaType.INTEGER.name().toLowerCase());
+        return property;
+    }
 
-	@Test
-	public void addPropertiesToGraphTableTest() {
+    @Test
+    public void addPropertiesToGraphTableTest() {
 
-		// Map<String, PropertyDefinition> properties = new HashMap<String,
-		// PropertyDefinition>();
-		// String propName = "myProp";
-		// PropertyDefinition property = buildPropertyDefinition();
-		//
-		// List<PropertyConstraint> constraints = buildConstraints();
-		// property.setConstraints(constraints);
-		//
-		// properties.put(propName, property);
-		//
-		// GraphNeighbourTable graphNeighbourTable = new GraphNeighbourTable();
-		// ResourceData resourceData = new ResourceData();
-		// String resourceName = "my-resource";
-		// String resourceVersion = "1.0";
-		// String resourceId = resourceName + "." + resourceVersion;
-		// resourceData.setUniqueId(resourceId);
-		// int resourceIndex = graphNeighbourTable.addNode(resourceData);
-		//
-		// heatParametersOperation.addPropertiesToGraphTable(properties,
-		// graphNeighbourTable, resourceIndex, resourceId);
-		//
-		// assertEquals(2, graphNeighbourTable.getNodes().size());
-		// assertEquals(1, graphNeighbourTable.getDirectedEdges().size());
-		// List<GraphNode> nodes = graphNeighbourTable.getNodes();
-		// boolean nodeFound = false;
-		// for (GraphNode neo4jNode : nodes) {
-		// if (neo4jNode instanceof PropertyData) {
-		// PropertyData propertyData = (PropertyData)neo4jNode;
-		// assertEquals("check property unique id", resourceId + "." + propName,
-		// propertyData.getUniqueId());
-		// assertEquals(property.getDescription(),
-		// propertyData.getPropertyDataDefinition().getDescription());
-		// nodeFound = true;
-		// }
-		// }
-		// assertEquals("looking for PropertyData object in table", true,
-		// nodeFound);
-		//
-		// NodeRelation nodeRelation =
-		// graphNeighbourTable.getDirectedEdges().get(0);
-		// assertEquals("check from index to index edge", 0,
-		// nodeRelation.getFromIndex());
-		// assertEquals("check from index to index edge", 1,
-		// nodeRelation.getToIndex());
-		// assertEquals("check edge type",
-		// GraphEdgePropertiesDictionary.PROPERTY,
-		// nodeRelation.getEdge().getEdgeType());
-		// assertEquals("check propert name on edge", true,
-		// nodeRelation.getEdge().getProperties().values().contains(propName));
-	}
+        // Map<String, PropertyDefinition> properties = new HashMap<String,
+        // PropertyDefinition>();
+        // String propName = "myProp";
+        // PropertyDefinition property = buildPropertyDefinition();
+        //
+        // List<PropertyConstraint> constraints = buildConstraints();
+        // property.setConstraints(constraints);
+        //
+        // properties.put(propName, property);
+        //
+        // GraphNeighbourTable graphNeighbourTable = new GraphNeighbourTable();
+        // ResourceData resourceData = new ResourceData();
+        // String resourceName = "my-resource";
+        // String resourceVersion = "1.0";
+        // String resourceId = resourceName + "." + resourceVersion;
+        // resourceData.setUniqueId(resourceId);
+        // int resourceIndex = graphNeighbourTable.addNode(resourceData);
+        //
+        // heatParametersOperation.addPropertiesToGraphTable(properties,
+        // graphNeighbourTable, resourceIndex, resourceId);
+        //
+        // assertEquals(2, graphNeighbourTable.getNodes().size());
+        // assertEquals(1, graphNeighbourTable.getDirectedEdges().size());
+        // List<GraphNode> nodes = graphNeighbourTable.getNodes();
+        // boolean nodeFound = false;
+        // for (GraphNode neo4jNode : nodes) {
+        // if (neo4jNode instanceof PropertyData) {
+        // PropertyData propertyData = (PropertyData)neo4jNode;
+        // assertEquals("check property unique id", resourceId + "." + propName,
+        // propertyData.getUniqueId());
+        // assertEquals(property.getDescription(),
+        // propertyData.getPropertyDataDefinition().getDescription());
+        // nodeFound = true;
+        // }
+        // }
+        // assertEquals("looking for PropertyData object in table", true,
+        // nodeFound);
+        //
+        // NodeRelation nodeRelation =
+        // graphNeighbourTable.getDirectedEdges().get(0);
+        // assertEquals("check from index to index edge", 0,
+        // nodeRelation.getFromIndex());
+        // assertEquals("check from index to index edge", 1,
+        // nodeRelation.getToIndex());
+        // assertEquals("check edge type",
+        // GraphEdgePropertiesDictionary.PROPERTY,
+        // nodeRelation.getEdge().getEdgeType());
+        // assertEquals("check propert name on edge", true,
+        // nodeRelation.getEdge().getProperties().values().contains(propName));
+    }
 
-	@Test
-	public void convertConstraintsTest() {
+    @Test
+    public void convertConstraintsTest() {
 
-		List<PropertyConstraint> constraints = buildConstraints();
-		List<String> convertedStringConstraints = propertyOperation.convertConstraintsToString(constraints);
-		assertEquals("constraints size", constraints.size(), convertedStringConstraints.size());
+        List<PropertyConstraint> constraints = buildConstraints();
+        List<String> convertedStringConstraints = propertyOperation.convertConstraintsToString(constraints);
+        assertEquals("constraints size", constraints.size(), convertedStringConstraints.size());
 
-		List<PropertyConstraint> convertedConstraints = propertyOperation
-				.convertConstraints(convertedStringConstraints);
-		assertEquals("check size of constraints", constraints.size(), convertedConstraints.size());
+        List<PropertyConstraint> convertedConstraints = propertyOperation.convertConstraints(convertedStringConstraints);
+        assertEquals("check size of constraints", constraints.size(), convertedConstraints.size());
 
-		Set<String> constraintsClasses = new HashSet<String>();
-		for (PropertyConstraint propertyConstraint : constraints) {
-			constraintsClasses.add(propertyConstraint.getClass().getName());
-		}
+        Set<String> constraintsClasses = new HashSet<>();
+        for (PropertyConstraint propertyConstraint : constraints) {
+            constraintsClasses.add(propertyConstraint.getClass().getName());
+        }
 
-		for (PropertyConstraint propertyConstraint : convertedConstraints) {
-			assertTrue("check all classes generated",
-					constraintsClasses.contains(propertyConstraint.getClass().getName()));
-		}
-	}
+        for (PropertyConstraint propertyConstraint : convertedConstraints) {
+            assertTrue("check all classes generated", constraintsClasses.contains(propertyConstraint.getClass().getName()));
+        }
+    }
 
-	@Test
-	public void testIsPropertyDefaultValueValid_NoDefault() {
-		PropertyDefinition property = new PropertyDefinition();
-		property.setName("myProperty");
-		property.setType(ToscaPropertyType.BOOLEAN.getType());
-		assertTrue(propertyOperation.isPropertyDefaultValueValid(property, null));
-	}
+    @Test
+    public void testIsPropertyDefaultValueValid_NoDefault() {
+        PropertyDefinition property = new PropertyDefinition();
+        property.setName("myProperty");
+        property.setType(ToscaPropertyType.BOOLEAN.getType());
+        assertTrue(propertyOperation.isPropertyDefaultValueValid(property, null));
+    }
 
-	@Test
-	public void testIsPropertyDefaultValueValid_ValidDefault() {
-		PropertyDefinition property = new PropertyDefinition();
-		property.setName("myProperty");
-		property.setType(ToscaPropertyType.INTEGER.getType());
-		property.setDefaultValue("50");
-		assertTrue(propertyOperation.isPropertyDefaultValueValid(property, null));
-	}
+    @Test
+    public void testIsPropertyDefaultValueValid_ValidDefault() {
+        PropertyDefinition property = new PropertyDefinition();
+        property.setName("myProperty");
+        property.setType(ToscaPropertyType.INTEGER.getType());
+        property.setDefaultValue("50");
+        assertTrue(propertyOperation.isPropertyDefaultValueValid(property, null));
+    }
 
-	@Test
-	public void testIsPropertyDefaultValueValid_InvalidDefault() {
-		PropertyDefinition property = new PropertyDefinition();
-		property.setName("myProperty");
-		property.setType(ToscaPropertyType.BOOLEAN.getType());
-		property.setDefaultValue("50");
-		assertFalse(propertyOperation.isPropertyDefaultValueValid(property, null));
-	}
+    @Test
+    public void testIsPropertyDefaultValueValid_InvalidDefault() {
+        PropertyDefinition property = new PropertyDefinition();
+        property.setName("myProperty");
+        property.setType(ToscaPropertyType.BOOLEAN.getType());
+        property.setDefaultValue("50");
+        assertFalse(propertyOperation.isPropertyDefaultValueValid(property, null));
+    }
 
-	private List<PropertyConstraint> buildConstraints() {
-		List<PropertyConstraint> constraints = new ArrayList<PropertyConstraint>();
-		GreaterThanConstraint propertyConstraint1 = new GreaterThanConstraint("0");
-		LessOrEqualConstraint propertyConstraint2 = new LessOrEqualConstraint("10");
-		List<String> range = new ArrayList<String>();
-		range.add("0");
-		range.add("100");
-		InRangeConstraint propertyConstraint3 = new InRangeConstraint(range);
-		constraints.add(propertyConstraint1);
-		constraints.add(propertyConstraint2);
-		constraints.add(propertyConstraint3);
-		return constraints;
-	}
+    private List<PropertyConstraint> buildConstraints() {
+        List<PropertyConstraint> constraints = new ArrayList<>();
+        GreaterThanConstraint propertyConstraint1 = new GreaterThanConstraint("0");
+        LessOrEqualConstraint propertyConstraint2 = new LessOrEqualConstraint("10");
+        List<String> range = new ArrayList<>();
+        range.add("0");
+        range.add("100");
+        InRangeConstraint propertyConstraint3 = new InRangeConstraint(range);
+        constraints.add(propertyConstraint1);
+        constraints.add(propertyConstraint2);
+        constraints.add(propertyConstraint3);
+        return constraints;
+    }
 
-	@Test
-	public void findPropertyValueBestMatch1() {
+    @Test
+    public void findPropertyValueBestMatch1() {
 
-		String propertyUniqueId = "x1";
-		ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
-		instanceProperty.setValue("v1");
-		instanceProperty.setDefaultValue("vv1");
-		List<String> path = new ArrayList<>();
-		path.add("node1");
-		path.add("node2");
-		path.add("node3");
-		instanceProperty.setPath(path);
+        String propertyUniqueId = "x1";
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setValue("v1");
+        instanceProperty.setDefaultValue("vv1");
+        List<String> path = new ArrayList<>();
+        path.add("node1");
+        path.add("node2");
+        path.add("node3");
+        instanceProperty.setPath(path);
 
-		Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<String, ComponentInstanceProperty>();
-		ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
-		instanceProperty1.setValue("v1node1");
-		instanceIdToValue.put("node1", instanceProperty1);
+        Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<>();
+        ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
+        instanceProperty1.setValue("v1node1");
+        instanceIdToValue.put("node1", instanceProperty1);
 
-		ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
-		instanceProperty2.setValue("v1node2");
-		instanceIdToValue.put("node2", instanceProperty2);
+        ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
+        instanceProperty2.setValue("v1node2");
+        instanceIdToValue.put("node2", instanceProperty2);
 
-		ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty();
-		instanceProperty3.setValue("v1node3");
-		instanceIdToValue.put("node3", instanceProperty3);
+        ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty();
+        instanceProperty3.setValue("v1node3");
+        instanceIdToValue.put("node3", instanceProperty3);
 
-		propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
+        propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
 
-		assertEquals("check value", "v1node1", instanceProperty.getValue());
-		assertEquals("check default value", "v1node2", instanceProperty.getDefaultValue());
+        assertEquals("check value", "v1node1", instanceProperty.getValue());
+        assertEquals("check default value", "v1node2", instanceProperty.getDefaultValue());
 
-	}
+    }
 
-	@Test
-	public void findPropertyValueBestMatch2() {
+    @Test
+    public void findPropertyValueBestMatch2() {
 
-		String propertyUniqueId = "x1";
-		ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
-		instanceProperty.setValue("v1");
-		instanceProperty.setDefaultValue("vv1");
-		List<String> path = new ArrayList<>();
-		path.add("node1");
-		path.add("node2");
-		path.add("node3");
-		instanceProperty.setPath(path);
+        String propertyUniqueId = "x1";
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setValue("v1");
+        instanceProperty.setDefaultValue("vv1");
+        List<String> path = new ArrayList<>();
+        path.add("node1");
+        path.add("node2");
+        path.add("node3");
+        instanceProperty.setPath(path);
 
-		Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<String, ComponentInstanceProperty>();
+        Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<>();
 
-		ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
-		instanceProperty2.setValue("v1node2");
-		instanceProperty2.setValueUniqueUid("aaaa");
-		instanceIdToValue.put("node2", instanceProperty2);
+        ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
+        instanceProperty2.setValue("v1node2");
+        instanceProperty2.setValueUniqueUid("aaaa");
+        instanceIdToValue.put("node2", instanceProperty2);
 
-		propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
+        propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
 
-		assertEquals("check value", "v1node2", instanceProperty.getValue());
-		assertEquals("check default value", "vv1", instanceProperty.getDefaultValue());
-		assertNull("check value unique id is null", instanceProperty.getValueUniqueUid());
+        assertEquals("check value", "v1node2", instanceProperty.getValue());
+        assertEquals("check default value", "vv1", instanceProperty.getDefaultValue());
+        assertNull("check value unique id is null", instanceProperty.getValueUniqueUid());
 
-	}
+    }
 
-	@Test
-	public void findPropertyValueBestMatch3() {
+    @Test
+    public void findPropertyValueBestMatch3() {
 
-		String propertyUniqueId = "x1";
-		ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
-		instanceProperty.setValue("v1");
-		instanceProperty.setDefaultValue("vv1");
-		List<String> path = new ArrayList<>();
-		path.add("node1");
-		path.add("node2");
-		path.add("node3");
-		instanceProperty.setPath(path);
+        String propertyUniqueId = "x1";
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setValue("v1");
+        instanceProperty.setDefaultValue("vv1");
+        List<String> path = new ArrayList<>();
+        path.add("node1");
+        path.add("node2");
+        path.add("node3");
+        instanceProperty.setPath(path);
 
-		Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<String, ComponentInstanceProperty>();
-		ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
-		instanceProperty1.setValue("v1node1");
-		instanceProperty1.setValueUniqueUid("aaaa");
-		instanceIdToValue.put("node1", instanceProperty1);
+        Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<>();
+        ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
+        instanceProperty1.setValue("v1node1");
+        instanceProperty1.setValueUniqueUid("aaaa");
+        instanceIdToValue.put("node1", instanceProperty1);
 
-		ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty();
-		instanceProperty3.setValue("v1node3");
-		instanceIdToValue.put("node3", instanceProperty3);
+        ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty();
+        instanceProperty3.setValue("v1node3");
+        instanceIdToValue.put("node3", instanceProperty3);
 
-		propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
+        propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
 
-		assertEquals("check value", "v1node1", instanceProperty.getValue());
-		assertEquals("check default value", "v1node3", instanceProperty.getDefaultValue());
-		assertEquals("check valid unique id", instanceProperty1.getValueUniqueUid(),
-				instanceProperty.getValueUniqueUid());
+        assertEquals("check value", "v1node1", instanceProperty.getValue());
+        assertEquals("check default value", "v1node3", instanceProperty.getDefaultValue());
+        assertEquals("check valid unique id", instanceProperty1.getValueUniqueUid(), instanceProperty.getValueUniqueUid());
 
-	}
+    }
 
-	@Test
-	public void findPropertyValueBestMatch1Rules() {
+    @Test
+    public void findPropertyValueBestMatch1Rules() {
 
-		String propertyUniqueId = "x1";
-		ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
-		instanceProperty.setValue("v1");
-		instanceProperty.setDefaultValue("vv1");
-		List<String> path = new ArrayList<>();
-		path.add("node1");
-		path.add("node2");
-		path.add("node3");
-		instanceProperty.setPath(path);
+        String propertyUniqueId = "x1";
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setValue("v1");
+        instanceProperty.setDefaultValue("vv1");
+        List<String> path = new ArrayList<>();
+        path.add("node1");
+        path.add("node2");
+        path.add("node3");
+        instanceProperty.setPath(path);
 
-		Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<String, ComponentInstanceProperty>();
-		ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
-		instanceProperty1.setValue("v1node1");
+        Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<>();
+        ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
+        instanceProperty1.setValue("v1node1");
 
-		List<PropertyRule> rules = new ArrayList<>();
-		PropertyRule propertyRule = new PropertyRule();
-		String[] ruleArr = { "node1", ".+", "node3" };
-		List<String> rule1 = new ArrayList<>(Arrays.asList(ruleArr));
-		propertyRule.setRule(rule1);
-		propertyRule.setValue("88");
-		rules.add(propertyRule);
-		instanceProperty1.setRules(rules);
+        List<PropertyRule> rules = new ArrayList<>();
+        PropertyRule propertyRule = new PropertyRule();
+        String[] ruleArr = { "node1", ".+", "node3" };
+        List<String> rule1 = new ArrayList<>(Arrays.asList(ruleArr));
+        propertyRule.setRule(rule1);
+        propertyRule.setValue("88");
+        rules.add(propertyRule);
+        instanceProperty1.setRules(rules);
 
-		instanceIdToValue.put("node1", instanceProperty1);
+        instanceIdToValue.put("node1", instanceProperty1);
 
-		ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
-		instanceProperty2.setValue("v1node2");
-		instanceIdToValue.put("node2", instanceProperty2);
+        ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
+        instanceProperty2.setValue("v1node2");
+        instanceIdToValue.put("node2", instanceProperty2);
 
-		ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty();
-		instanceProperty3.setValue("v1node3");
-		instanceIdToValue.put("node3", instanceProperty3);
+        ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty();
+        instanceProperty3.setValue("v1node3");
+        instanceIdToValue.put("node3", instanceProperty3);
 
-		propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
+        propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
 
-		assertEquals("check value", propertyRule.getValue(), instanceProperty.getValue());
-		assertEquals("check default value", "v1node2", instanceProperty.getDefaultValue());
+        assertEquals("check value", propertyRule.getValue(), instanceProperty.getValue());
+        assertEquals("check default value", "v1node2", instanceProperty.getDefaultValue());
 
-	}
+    }
 
-	@Test
-	public void findPropertyValueBestMatch2Rules() {
+    @Test
+    public void findPropertyValueBestMatch2Rules() {
 
-		String propertyUniqueId = "x1";
-		ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
-		instanceProperty.setValue("v1");
-		instanceProperty.setDefaultValue("vv1");
-		List<String> path = new ArrayList<>();
-		path.add("node1");
-		path.add("node2");
-		path.add("node3");
-		instanceProperty.setPath(path);
+        String propertyUniqueId = "x1";
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setValue("v1");
+        instanceProperty.setDefaultValue("vv1");
+        List<String> path = new ArrayList<>();
+        path.add("node1");
+        path.add("node2");
+        path.add("node3");
+        instanceProperty.setPath(path);
 
-		Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<String, ComponentInstanceProperty>();
-		ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
-		instanceProperty1.setValue("v1node1");
+        Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<>();
+        ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
+        instanceProperty1.setValue("v1node1");
 
-		List<PropertyRule> rules = new ArrayList<>();
-		PropertyRule propertyRule1 = new PropertyRule();
-		String[] ruleArr1 = { "node1", "node2", ".+" };
-		List<String> rule1 = new ArrayList<>(Arrays.asList(ruleArr1));
-		propertyRule1.setRule(rule1);
-		propertyRule1.setValue("88");
+        List<PropertyRule> rules = new ArrayList<>();
+        PropertyRule propertyRule1 = new PropertyRule();
+        String[] ruleArr1 = { "node1", "node2", ".+" };
+        List<String> rule1 = new ArrayList<>(Arrays.asList(ruleArr1));
+        propertyRule1.setRule(rule1);
+        propertyRule1.setValue("88");
 
-		PropertyRule propertyRule2 = new PropertyRule();
-		String[] ruleArr2 = { "node1", "node2", "node3" };
-		List<String> rule2 = new ArrayList<>(Arrays.asList(ruleArr2));
-		propertyRule2.setRule(rule2);
-		propertyRule2.setValue("99");
+        PropertyRule propertyRule2 = new PropertyRule();
+        String[] ruleArr2 = { "node1", "node2", "node3" };
+        List<String> rule2 = new ArrayList<>(Arrays.asList(ruleArr2));
+        propertyRule2.setRule(rule2);
+        propertyRule2.setValue("99");
 
-		rules.add(propertyRule2);
-		rules.add(propertyRule1);
+        rules.add(propertyRule2);
+        rules.add(propertyRule1);
 
-		instanceProperty1.setRules(rules);
+        instanceProperty1.setRules(rules);
 
-		instanceIdToValue.put("node1", instanceProperty1);
+        instanceIdToValue.put("node1", instanceProperty1);
 
-		ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
-		instanceProperty2.setValue("v1node2");
-		instanceIdToValue.put("node2", instanceProperty2);
+        ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
+        instanceProperty2.setValue("v1node2");
+        instanceIdToValue.put("node2", instanceProperty2);
 
-		ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty();
-		instanceProperty3.setValue("v1node3");
-		instanceIdToValue.put("node3", instanceProperty3);
+        ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty();
+        instanceProperty3.setValue("v1node3");
+        instanceIdToValue.put("node3", instanceProperty3);
 
-		propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
+        propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
 
-		assertEquals("check value", propertyRule2.getValue(), instanceProperty.getValue());
-		assertEquals("check default value", "v1node2", instanceProperty.getDefaultValue());
+        assertEquals("check value", propertyRule2.getValue(), instanceProperty.getValue());
+        assertEquals("check default value", "v1node2", instanceProperty.getDefaultValue());
 
-	}
+    }
 
-	@Test
-	public void findPropertyValueBestMatch1RuleLowLevel() {
+    @Test
+    public void findPropertyValueBestMatch1RuleLowLevel() {
 
-		String propertyUniqueId = "x1";
-		ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
-		instanceProperty.setValue("v1");
-		instanceProperty.setDefaultValue("vv1");
-		List<String> path = new ArrayList<>();
-		path.add("node1");
-		path.add("node2");
-		path.add("node3");
-		instanceProperty.setPath(path);
+        String propertyUniqueId = "x1";
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setValue("v1");
+        instanceProperty.setDefaultValue("vv1");
+        List<String> path = new ArrayList<>();
+        path.add("node1");
+        path.add("node2");
+        path.add("node3");
+        instanceProperty.setPath(path);
 
-		Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<String, ComponentInstanceProperty>();
-		ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
-		instanceProperty1.setValue("v1node1");
+        Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<>();
+        ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
+        instanceProperty1.setValue("v1node1");
 
-		List<PropertyRule> rules = new ArrayList<>();
-		PropertyRule propertyRule1 = new PropertyRule();
-		String[] ruleArr1 = { "node1", "node2", ".+" };
-		List<String> rule1 = new ArrayList<>(Arrays.asList(ruleArr1));
-		propertyRule1.setRule(rule1);
-		propertyRule1.setValue("88");
+        List<PropertyRule> rules = new ArrayList<>();
+        PropertyRule propertyRule1 = new PropertyRule();
+        String[] ruleArr1 = { "node1", "node2", ".+" };
+        List<String> rule1 = new ArrayList<>(Arrays.asList(ruleArr1));
+        propertyRule1.setRule(rule1);
+        propertyRule1.setValue("88");
 
-		PropertyRule propertyRule2 = new PropertyRule();
-		String[] ruleArr2 = { "node1", "node2", "node3" };
-		List<String> rule2 = new ArrayList<>(Arrays.asList(ruleArr2));
-		propertyRule2.setRule(rule2);
-		propertyRule2.setValue("99");
+        PropertyRule propertyRule2 = new PropertyRule();
+        String[] ruleArr2 = { "node1", "node2", "node3" };
+        List<String> rule2 = new ArrayList<>(Arrays.asList(ruleArr2));
+        propertyRule2.setRule(rule2);
+        propertyRule2.setValue("99");
 
-		rules.add(propertyRule2);
-		rules.add(propertyRule1);
+        rules.add(propertyRule2);
+        rules.add(propertyRule1);
 
-		instanceProperty1.setRules(rules);
+        instanceProperty1.setRules(rules);
 
-		instanceIdToValue.put("node1", instanceProperty1);
+        instanceIdToValue.put("node1", instanceProperty1);
 
-		ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
-		instanceProperty2.setValue("v1node2");
+        ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
+        instanceProperty2.setValue("v1node2");
 
-		List<PropertyRule> rules3 = new ArrayList<>();
-		PropertyRule propertyRule3 = new PropertyRule();
-		String[] ruleArr3 = { "node2", "node3" };
-		List<String> rule3 = new ArrayList<>(Arrays.asList(ruleArr3));
-		propertyRule3.setRule(rule3);
-		propertyRule3.setValue("77");
-		rules3.add(propertyRule3);
+        List<PropertyRule> rules3 = new ArrayList<>();
+        PropertyRule propertyRule3 = new PropertyRule();
+        String[] ruleArr3 = { "node2", "node3" };
+        List<String> rule3 = new ArrayList<>(Arrays.asList(ruleArr3));
+        propertyRule3.setRule(rule3);
+        propertyRule3.setValue("77");
+        rules3.add(propertyRule3);
 
-		instanceProperty2.setRules(rules3);
-		instanceIdToValue.put("node2", instanceProperty2);
+        instanceProperty2.setRules(rules3);
+        instanceIdToValue.put("node2", instanceProperty2);
 
-		ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty();
-		instanceProperty3.setValue("v1node3");
-		instanceIdToValue.put("node3", instanceProperty3);
+        ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty();
+        instanceProperty3.setValue("v1node3");
+        instanceIdToValue.put("node3", instanceProperty3);
 
-		propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
+        propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
 
-		assertEquals("check value", propertyRule2.getValue(), instanceProperty.getValue());
-		assertEquals("check default value", propertyRule3.getValue(), instanceProperty.getDefaultValue());
+        assertEquals("check value", propertyRule2.getValue(), instanceProperty.getValue());
+        assertEquals("check default value", propertyRule3.getValue(), instanceProperty.getDefaultValue());
 
-	}
+    }
 
-	@Test
-	public void findPropertyValueBestMatchDefaultValueNotChanged() {
+    @Test
+    public void findPropertyValueBestMatchDefaultValueNotChanged() {
 
-		String propertyUniqueId = "x1";
-		ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
-		instanceProperty.setValue("v1");
-		instanceProperty.setDefaultValue("vv1");
-		List<String> path = new ArrayList<>();
-		path.add("node1");
-		path.add("node2");
-		path.add("node3");
-		instanceProperty.setPath(path);
+        String propertyUniqueId = "x1";
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setValue("v1");
+        instanceProperty.setDefaultValue("vv1");
+        List<String> path = new ArrayList<>();
+        path.add("node1");
+        path.add("node2");
+        path.add("node3");
+        instanceProperty.setPath(path);
 
-		Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<String, ComponentInstanceProperty>();
-		ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
-		instanceProperty1.setValue("v1node1");
+        Map<String, ComponentInstanceProperty> instanceIdToValue = new HashMap<>();
+        ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty();
+        instanceProperty1.setValue("v1node1");
 
-		List<PropertyRule> rules = new ArrayList<>();
-		PropertyRule propertyRule1 = new PropertyRule();
-		String[] ruleArr1 = { "node1", "node2", ".+" };
-		List<String> rule1 = new ArrayList<>(Arrays.asList(ruleArr1));
-		propertyRule1.setRule(rule1);
-		propertyRule1.setValue("88");
+        List<PropertyRule> rules = new ArrayList<>();
+        PropertyRule propertyRule1 = new PropertyRule();
+        String[] ruleArr1 = { "node1", "node2", ".+" };
+        List<String> rule1 = new ArrayList<>(Arrays.asList(ruleArr1));
+        propertyRule1.setRule(rule1);
+        propertyRule1.setValue("88");
 
-		PropertyRule propertyRule2 = new PropertyRule();
-		String[] ruleArr2 = { "node1", "node2", "node3" };
-		List<String> rule2 = new ArrayList<>(Arrays.asList(ruleArr2));
-		propertyRule2.setRule(rule2);
-		propertyRule2.setValue("99");
+        PropertyRule propertyRule2 = new PropertyRule();
+        String[] ruleArr2 = { "node1", "node2", "node3" };
+        List<String> rule2 = new ArrayList<>(Arrays.asList(ruleArr2));
+        propertyRule2.setRule(rule2);
+        propertyRule2.setValue("99");
 
-		rules.add(propertyRule2);
-		rules.add(propertyRule1);
+        rules.add(propertyRule2);
+        rules.add(propertyRule1);
 
-		instanceProperty1.setRules(rules);
+        instanceProperty1.setRules(rules);
 
-		instanceIdToValue.put("node1", instanceProperty1);
+        instanceIdToValue.put("node1", instanceProperty1);
 
-		ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
-		instanceProperty2.setValue("v1node2");
+        ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty();
+        instanceProperty2.setValue("v1node2");
 
-		List<PropertyRule> rules3 = new ArrayList<>();
-		PropertyRule propertyRule3 = new PropertyRule();
-		String[] ruleArr3 = { "node2", "node333" };
-		List<String> rule3 = new ArrayList<>(Arrays.asList(ruleArr3));
-		propertyRule3.setRule(rule3);
-		propertyRule3.setValue("77");
-		rules3.add(propertyRule3);
+        List<PropertyRule> rules3 = new ArrayList<>();
+        PropertyRule propertyRule3 = new PropertyRule();
+        String[] ruleArr3 = { "node2", "node333" };
+        List<String> rule3 = new ArrayList<>(Arrays.asList(ruleArr3));
+        propertyRule3.setRule(rule3);
+        propertyRule3.setValue("77");
+        rules3.add(propertyRule3);
 
-		instanceProperty2.setRules(rules3);
-		instanceIdToValue.put("node2", instanceProperty2);
+        instanceProperty2.setRules(rules3);
+        instanceIdToValue.put("node2", instanceProperty2);
 
-		propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
+        propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
 
-		assertEquals("check value", propertyRule2.getValue(), instanceProperty.getValue());
-		assertEquals("check default value", "vv1", instanceProperty.getDefaultValue());
+        assertEquals("check value", propertyRule2.getValue(), instanceProperty.getValue());
+        assertEquals("check default value", "vv1", instanceProperty.getDefaultValue());
 
 	}
 
@@ -573,38 +536,6 @@
 		testSubject = createTestSubject();
 		result = testSubject.convertPropertyDataToPropertyDefinition(propertyDataResult, propertyName, resourceId);
 	}
-
-	
-	@Test
-	public void testAddPropertiesToGraph() throws Exception {
-		PropertyOperation testSubject;
-		Map<String, PropertyDefinition> properties = null;
-		String resourceId = "";
-		Map<String, DataTypeDefinition> dataTypes = null;
-		TitanOperationStatus result;
-
-		// test 1
-		testSubject = createTestSubject();
-		properties = null;
-		result = testSubject.addPropertiesToGraph(properties, resourceId, dataTypes);
-	}
-
-	
-	@Test
-	public void testAddPropertiesToGraph_1() throws Exception {
-		PropertyOperation testSubject;
-		TitanVertex metadataVertex = null;
-		Map<String, PropertyDefinition> properties = null;
-		Map<String, DataTypeDefinition> dataTypes = null;
-		String resourceId = "";
-		TitanOperationStatus result;
-
-		// test 1
-		testSubject = createTestSubject();
-		properties = null;
-		result = testSubject.addPropertiesToGraph(metadataVertex, properties, dataTypes, resourceId);
-	}
-
 	
 	@Test
 	public void testAddProperty() throws Exception {
@@ -673,19 +604,6 @@
 		result = testSubject.getTitanGenericDao();
 	}
 
-	
-	@Test
-	public void testDeleteProperty() throws Exception {
-		PropertyOperation testSubject;
-		String propertyId = "";
-		Either<PropertyData, StorageOperationStatus> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.deleteProperty(propertyId);
-	}
-
-	
 	@Test
 	public void testDeletePropertyFromGraph() throws Exception {
 		PropertyOperation testSubject;
@@ -1183,29 +1101,4 @@
 		testSubject = createTestSubject();
 		result = testSubject.updateDataType(newDataTypeDefinition, oldDataTypeDefinition);
 	}
-
-	
-	@Test
-	public void testIsValueToscaFunction() throws Exception {
-		PropertyOperation testSubject;
-		String type = "";
-		String value = "";
-		boolean result;
-
-		// test 1
-		testSubject = createTestSubject();
-		value = null;
-		result = testSubject.isValueToscaFunction(type, value);
-		Assert.assertEquals(false, result);
-
-		// test 2
-		testSubject = createTestSubject();
-		value = "";
-		result = testSubject.isValueToscaFunction(type, value);
-		Assert.assertEquals(false, result);
-	}
-
-	// add all rule types
-	// add rule with size = 1(instance itself = ALL). relevant for VLi. equals
-	// to X.*.*.* in all paths size
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java
index 8f8baea..506bec4 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java
@@ -23,11 +23,7 @@
 import com.thinkaurelius.titan.core.TitanGraph;
 import com.thinkaurelius.titan.core.TitanVertex;
 import fj.data.Either;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.*;
 import org.junit.rules.TestName;
 import org.junit.runner.RunWith;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
@@ -61,554 +57,555 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.*;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:application-context-test.xml")
 public class ToscaElementLifecycleOperationTest extends ModelTestBase {
 
-	@javax.annotation.Resource
-	protected TitanDao titanDao;
+    @javax.annotation.Resource
+    protected TitanDao titanDao;
 
-	@javax.annotation.Resource
-	private NodeTypeOperation nodeTypeOperation;
+    @javax.annotation.Resource
+    private NodeTypeOperation nodeTypeOperation;
 
-	@javax.annotation.Resource
-	private TopologyTemplateOperation topologyTemplateOperation;
+    @javax.annotation.Resource
+    private TopologyTemplateOperation topologyTemplateOperation;
 
-	@javax.annotation.Resource
-	private ToscaElementLifecycleOperation lifecycleOperation;
+    @javax.annotation.Resource
+    private ToscaElementLifecycleOperation lifecycleOperation;
 
-	String categoryName = "category";
-	String subcategory = "mycategory";
-	String outputDirectory = "C:\\Output";
+    String categoryName = "category";
+    String subcategory = "mycategory";
+    String outputDirectory = "C:\\Output";
 
-	@Rule
-	public TestName name = new TestName();
+    @Rule
+    public TestName name = new TestName();
 
-	@BeforeClass
-	public static void initLifecycleOperation() {
-		ModelTestBase.init();
-	}
+    @BeforeClass
+    public static void initLifecycleOperation() {
+        ModelTestBase.init();
+    }
 
-	private GraphVertex ownerVertex;
-	private GraphVertex modifierVertex;
-	private GraphVertex vfVertex;
-	private GraphVertex serviceVertex;
-	private GraphVertex rootVertex;
+    private GraphVertex ownerVertex;
+    private GraphVertex modifierVertex;
+    private GraphVertex vfVertex;
+    private GraphVertex serviceVertex;
+    private GraphVertex rootVertex;
 
-	@Before
-	public void setupBefore() {
-		clearGraph();
-		createUsers();
-		createResourceCategory();
-		createServiceCategory();
-		GraphTestUtils.createRootCatalogVertex(titanDao);
-		rootVertex = createRootNodeType();
-		createNodeType("firstVf");
-		serviceVertex = createTopologyTemplate("firstService");
-	}
+    @Before
+    public void setupBefore() {
+        clearGraph();
+        createUsers();
+        createResourceCategory();
+        createServiceCategory();
+        GraphTestUtils.createRootCatalogVertex(titanDao);
+        rootVertex = createRootNodeType();
+        createNodeType("firstVf");
+        serviceVertex = createTopologyTemplate("firstService");
+    }
 
-	@Test
-	public void lifecycleTest() {
-		Either<ToscaElement, StorageOperationStatus> res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.findState((String) vfVertex.getMetadataProperty(GraphPropertyEnum.STATE)), vfVertex.getUniqueId(), modifierVertex.getUniqueId(),
-				ownerVertex.getUniqueId());
-		StorageOperationStatus status;
+    @Test
+    public void lifecycleTest() {
+        Either<ToscaElement, StorageOperationStatus> res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.findState((String) vfVertex.getMetadataProperty(GraphPropertyEnum.STATE)), vfVertex.getUniqueId(), modifierVertex.getUniqueId(),
+                ownerVertex.getUniqueId());
+        StorageOperationStatus status;
 
-		assertTrue(res.isLeft());
-		// 1-node type
-		// 2-vf
-		// 3- service
-		verifyInCatalogData(3, null);
+        assertTrue(res.isLeft());
+        // 1-node type
+        // 2-vf
+        // 3- service
+        verifyInCatalogData(3, null);
 
-		String id = res.left().value().getUniqueId();
+        String id = res.left().value().getUniqueId();
 
-		res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), modifierVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), modifierVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		verifyInCatalogData(3, null);
+        verifyInCatalogData(3, null);
 
-		PropertyDataDefinition prop55 = new PropertyDataDefinition();
-		prop55.setName("prop55");
-		prop55.setDefaultValue("def55");
+        PropertyDataDefinition prop55 = new PropertyDataDefinition();
+        prop55.setName("prop55");
+        prop55.setDefaultValue("def55");
 
-		status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop55, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop55, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		CapabilityDataDefinition cap1 = new CapabilityDataDefinition();
-		cap1.setName("cap1");
-		cap1.setDescription("create");
-		cap1.setUniqueId(UniqueIdBuilder.buildCapabilityUid(id, "cap1"));
+        CapabilityDataDefinition cap1 = new CapabilityDataDefinition();
+        cap1.setName("cap1");
+        cap1.setDescription("create");
+        cap1.setUniqueId(UniqueIdBuilder.buildCapabilityUid(id, "cap1"));
 
-		status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.CAPABILITIES, VertexTypeEnum.CAPABILTIES, cap1, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.CAPABILITIES, VertexTypeEnum.CAPABILTIES, cap1, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		prop55.setDefaultValue("AAAAAAAA");
-		status = nodeTypeOperation.updateToscaDataOfToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop55, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        prop55.setDefaultValue("AAAAAAAA");
+        status = nodeTypeOperation.updateToscaDataOfToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop55, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		cap1.setDescription("update");
+        cap1.setDescription("update");
 
-		status = nodeTypeOperation.updateToscaDataOfToscaElement(id, EdgeLabelEnum.CAPABILITIES, VertexTypeEnum.CAPABILTIES, cap1, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        status = nodeTypeOperation.updateToscaDataOfToscaElement(id, EdgeLabelEnum.CAPABILITIES, VertexTypeEnum.CAPABILTIES, cap1, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		PropertyDataDefinition prop66 = new PropertyDataDefinition();
-		prop66.setName("prop66");
-		prop66.setDefaultValue("def66");
+        PropertyDataDefinition prop66 = new PropertyDataDefinition();
+        prop66.setName("prop66");
+        prop66.setDefaultValue("def66");
 
-		status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop66, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop66, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		res = lifecycleOperation.requestCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        res = lifecycleOperation.requestCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		res = lifecycleOperation.startCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        res = lifecycleOperation.startCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		res = lifecycleOperation.certifyToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        res = lifecycleOperation.certifyToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		verifyInCatalogData(3, null);
-		
-		res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), modifierVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        verifyInCatalogData(3, null);
 
-		verifyInCatalogData(4, null);
-		
-		PropertyDataDefinition prop77 = new PropertyDataDefinition();
-		prop77.setName("prop77");
-		prop77.setDefaultValue("def77");
+        res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), modifierVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop77, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        verifyInCatalogData(4, null);
 
-		res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        PropertyDataDefinition prop77 = new PropertyDataDefinition();
+        prop77.setName("prop77");
+        prop77.setDefaultValue("def77");
 
-		res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop77, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		PropertyDataDefinition prop88 = new PropertyDataDefinition();
-		prop88.setName("prop88");
-		prop88.setDefaultValue("def88");
+        res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop88, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		res = lifecycleOperation.requestCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        PropertyDataDefinition prop88 = new PropertyDataDefinition();
+        prop88.setName("prop88");
+        prop88.setDefaultValue("def88");
 
-		res = lifecycleOperation.startCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop88, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		res = lifecycleOperation.certifyToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
-		verifyInCatalogData(3, null);
-		
-		res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        res = lifecycleOperation.requestCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		verifyInCatalogData(4, null);
-		
-		PropertyDataDefinition prop99 = new PropertyDataDefinition();
-		prop99.setName("prop99");
-		prop99.setDefaultValue("def99");
+        res = lifecycleOperation.startCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop99, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        res = lifecycleOperation.certifyToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
+        verifyInCatalogData(3, null);
 
-		res = lifecycleOperation.requestCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		res = lifecycleOperation.startCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        verifyInCatalogData(4, null);
 
-		status = nodeTypeOperation.deleteToscaDataElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, "prop99", JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        PropertyDataDefinition prop99 = new PropertyDataDefinition();
+        prop99.setName("prop99");
+        prop99.setDefaultValue("def99");
 
-		// cancel certification
-		res = lifecycleOperation.cancelOrFailCertification(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), LifecycleStateEnum.READY_FOR_CERTIFICATION);
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop99, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		res = lifecycleOperation.startCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
+        res = lifecycleOperation.requestCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		// fail certification
-		res = lifecycleOperation.cancelOrFailCertification(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
-		assertTrue(res.isLeft());
-		id = res.left().value().getUniqueId();
-		verifyInCatalogData(4, null);
-		// exportGraphMl(titanDao.getGraph().left().value());
+        res = lifecycleOperation.startCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-	}
+        status = nodeTypeOperation.deleteToscaDataElement(id, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, "prop99", JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-	@Test
-	public void serviceConformanceLevelTest() {
-		Either<ToscaElement, StorageOperationStatus> res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.findState((String) serviceVertex.getMetadataProperty(GraphPropertyEnum.STATE)), serviceVertex.getUniqueId(),
-				modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        // cancel certification
+        res = lifecycleOperation.cancelOrFailCertification(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), LifecycleStateEnum.READY_FOR_CERTIFICATION);
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		assertTrue(res.isLeft());
-		String id = res.left().value().getUniqueId();
+        res = lifecycleOperation.startCertificationToscaElement(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
 
-		res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), modifierVertex.getUniqueId());
-		assertTrue(res.isLeft());
+        // fail certification
+        res = lifecycleOperation.cancelOrFailCertification(id, modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
+        assertTrue(res.isLeft());
+        id = res.left().value().getUniqueId();
+        verifyInCatalogData(4, null);
+        // exportGraphMl(titanDao.getGraph().left().value());
 
-		String conformanceLevel = res.left().value().getMetadataValue(JsonPresentationFields.CONFORMANCE_LEVEL).toString();
-		assertEquals(conformanceLevel, ModelTestBase.configurationManager.getConfiguration().getToscaConformanceLevel());
-	}
+    }
 
-	@Test
-	public void catalogTest() {
-		// start position - 3 in catalog
-		List<String> expectedIds = new ArrayList<String>();
-		expectedIds.add(rootVertex.getUniqueId());
-		expectedIds.add(vfVertex.getUniqueId());
-		expectedIds.add(serviceVertex.getUniqueId());
+    @Test
+    public void serviceConformanceLevelTest() {
+        Either<ToscaElement, StorageOperationStatus> res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.findState((String) serviceVertex.getMetadataProperty(GraphPropertyEnum.STATE)), serviceVertex.getUniqueId(),
+                modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
 
-		verifyInCatalogData(3, expectedIds);
-		
-		GraphVertex vertex4 = createTopologyTemplate("topTemp4");
-		expectedIds.add(vertex4.getUniqueId());
-		verifyInCatalogData(4, expectedIds);
+        assertTrue(res.isLeft());
+        String id = res.left().value().getUniqueId();
 
-		Either<ToscaElement, StorageOperationStatus> res = lifecycleOperation.undoCheckout(vertex4.getUniqueId());
-		expectedIds.remove(vertex4.getUniqueId());
-		verifyInCatalogData(3, expectedIds);
+        res = lifecycleOperation.checkoutToscaElement(id, ownerVertex.getUniqueId(), modifierVertex.getUniqueId());
+        assertTrue(res.isLeft());
 
-		vertex4 = createTopologyTemplate("topTemp4");
-		expectedIds.add(vertex4.getUniqueId());
-		verifyInCatalogData(4, expectedIds);
+        String conformanceLevel = res.left().value().getMetadataValue(JsonPresentationFields.CONFORMANCE_LEVEL).toString();
+        assertEquals(conformanceLevel, ModelTestBase.configurationManager.getConfiguration().getToscaConformanceLevel());
+    }
 
-		res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.findState((String) vertex4.getMetadataProperty(GraphPropertyEnum.STATE)), vertex4.getUniqueId(), modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		Either<ToscaElement, StorageOperationStatus> certifyToscaElement = lifecycleOperation.certifyToscaElement(vertex4.getUniqueId(), modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(certifyToscaElement.isLeft());
-		expectedIds.remove(vertex4.getUniqueId());
-		String certifiedId = certifyToscaElement.left().value().getUniqueId();
-		expectedIds.add(certifiedId);
-		verifyInCatalogData(4, expectedIds);
-		
-		res = lifecycleOperation.checkoutToscaElement(certifiedId, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
-		assertTrue(certifyToscaElement.isLeft());
-		expectedIds.add(res.left().value().getUniqueId());
-		verifyInCatalogData(5, expectedIds);
-	}
+    @Test
+    public void catalogTest() {
+        // start position - 3 in catalog
+        List<String> expectedIds = new ArrayList<>();
+        expectedIds.add(rootVertex.getUniqueId());
+        expectedIds.add(vfVertex.getUniqueId());
+        expectedIds.add(serviceVertex.getUniqueId());
 
-	private void createResourceCategory() {
+        verifyInCatalogData(3, expectedIds);
 
-		GraphVertex cat = new GraphVertex(VertexTypeEnum.RESOURCE_CATEGORY);
-		Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>();
-		String catId = UniqueIdBuilder.buildComponentCategoryUid(categoryName, VertexTypeEnum.RESOURCE_CATEGORY);
-		cat.setUniqueId(catId);
-		metadataProperties.put(GraphPropertyEnum.UNIQUE_ID, catId);
-		metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.RESOURCE_CATEGORY.getName());
-		metadataProperties.put(GraphPropertyEnum.NAME, categoryName);
-		metadataProperties.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(categoryName));
-		cat.setMetadataProperties(metadataProperties);
-		cat.updateMetadataJsonWithCurrentMetadataProperties();
+        GraphVertex vertex4 = createTopologyTemplate("topTemp4");
+        expectedIds.add(vertex4.getUniqueId());
+        verifyInCatalogData(4, expectedIds);
 
-		GraphVertex subCat = new GraphVertex(VertexTypeEnum.RESOURCE_SUBCATEGORY);
-		metadataProperties = new HashMap<>();
-		String subCatId = UniqueIdBuilder.buildSubCategoryUid(cat.getUniqueId(), subcategory);
-		subCat.setUniqueId(subCatId);
-		metadataProperties.put(GraphPropertyEnum.UNIQUE_ID, subCatId);
-		metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.RESOURCE_SUBCATEGORY.getName());
-		metadataProperties.put(GraphPropertyEnum.NAME, subcategory);
-		metadataProperties.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(subcategory));
-		subCat.setMetadataProperties(metadataProperties);
-		subCat.updateMetadataJsonWithCurrentMetadataProperties();
+        Either<ToscaElement, StorageOperationStatus> res = lifecycleOperation.undoCheckout(vertex4.getUniqueId());
+        expectedIds.remove(vertex4.getUniqueId());
+        verifyInCatalogData(3, expectedIds);
+
+        vertex4 = createTopologyTemplate("topTemp4");
+        expectedIds.add(vertex4.getUniqueId());
+        verifyInCatalogData(4, expectedIds);
+
+        res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.findState((String) vertex4.getMetadataProperty(GraphPropertyEnum.STATE)), vertex4.getUniqueId(), modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        Either<ToscaElement, StorageOperationStatus> certifyToscaElement = lifecycleOperation.certifyToscaElement(vertex4.getUniqueId(), modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(certifyToscaElement.isLeft());
+        expectedIds.remove(vertex4.getUniqueId());
+        String certifiedId = certifyToscaElement.left().value().getUniqueId();
+        expectedIds.add(certifiedId);
+        verifyInCatalogData(4, expectedIds);
+
+        res = lifecycleOperation.checkoutToscaElement(certifiedId, modifierVertex.getUniqueId(), ownerVertex.getUniqueId());
+        assertTrue(certifyToscaElement.isLeft());
+        expectedIds.add(res.left().value().getUniqueId());
+        verifyInCatalogData(5, expectedIds);
+    }
+
+    private void createResourceCategory() {
+
+        GraphVertex cat = new GraphVertex(VertexTypeEnum.RESOURCE_CATEGORY);
+        Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>();
+        String catId = UniqueIdBuilder.buildComponentCategoryUid(categoryName, VertexTypeEnum.RESOURCE_CATEGORY);
+        cat.setUniqueId(catId);
+        metadataProperties.put(GraphPropertyEnum.UNIQUE_ID, catId);
+        metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.RESOURCE_CATEGORY.getName());
+        metadataProperties.put(GraphPropertyEnum.NAME, categoryName);
+        metadataProperties.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(categoryName));
+        cat.setMetadataProperties(metadataProperties);
+        cat.updateMetadataJsonWithCurrentMetadataProperties();
+
+        GraphVertex subCat = new GraphVertex(VertexTypeEnum.RESOURCE_SUBCATEGORY);
+        metadataProperties = new HashMap<>();
+        String subCatId = UniqueIdBuilder.buildSubCategoryUid(cat.getUniqueId(), subcategory);
+        subCat.setUniqueId(subCatId);
+        metadataProperties.put(GraphPropertyEnum.UNIQUE_ID, subCatId);
+        metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.RESOURCE_SUBCATEGORY.getName());
+        metadataProperties.put(GraphPropertyEnum.NAME, subcategory);
+        metadataProperties.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(subcategory));
+        subCat.setMetadataProperties(metadataProperties);
+        subCat.updateMetadataJsonWithCurrentMetadataProperties();
 
-		Either<GraphVertex, TitanOperationStatus> catRes = titanDao.createVertex(cat);
+        Either<GraphVertex, TitanOperationStatus> catRes = titanDao.createVertex(cat);
 
-		Either<GraphVertex, TitanOperationStatus> subCatRes = titanDao.createVertex(subCat);
+        Either<GraphVertex, TitanOperationStatus> subCatRes = titanDao.createVertex(subCat);
 
-		TitanOperationStatus status = titanDao.createEdge(catRes.left().value().getVertex(), subCatRes.left().value().getVertex(), EdgeLabelEnum.SUB_CATEGORY, new HashMap<>());
-		assertEquals(TitanOperationStatus.OK, status);
-	}
+        TitanOperationStatus status = titanDao.createEdge(catRes.left().value().getVertex(), subCatRes.left().value().getVertex(), EdgeLabelEnum.SUB_CATEGORY, new HashMap<>());
+        assertEquals(TitanOperationStatus.OK, status);
+    }
 
-	private void createServiceCategory() {
+    private void createServiceCategory() {
 
-		GraphVertex cat = new GraphVertex(VertexTypeEnum.SERVICE_CATEGORY);
-		Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>();
-		String catId = UniqueIdBuilder.buildComponentCategoryUid(categoryName, VertexTypeEnum.SERVICE_CATEGORY);
-		cat.setUniqueId(catId);
-		metadataProperties.put(GraphPropertyEnum.UNIQUE_ID, catId);
-		metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.SERVICE_CATEGORY.getName());
-		metadataProperties.put(GraphPropertyEnum.NAME, categoryName);
-		metadataProperties.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(categoryName));
-		cat.setMetadataProperties(metadataProperties);
-		cat.updateMetadataJsonWithCurrentMetadataProperties();
+        GraphVertex cat = new GraphVertex(VertexTypeEnum.SERVICE_CATEGORY);
+        Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>();
+        String catId = UniqueIdBuilder.buildComponentCategoryUid(categoryName, VertexTypeEnum.SERVICE_CATEGORY);
+        cat.setUniqueId(catId);
+        metadataProperties.put(GraphPropertyEnum.UNIQUE_ID, catId);
+        metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.SERVICE_CATEGORY.getName());
+        metadataProperties.put(GraphPropertyEnum.NAME, categoryName);
+        metadataProperties.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(categoryName));
+        cat.setMetadataProperties(metadataProperties);
+        cat.updateMetadataJsonWithCurrentMetadataProperties();
 
-		Either<GraphVertex, TitanOperationStatus> catRes = titanDao.createVertex(cat);
+        Either<GraphVertex, TitanOperationStatus> catRes = titanDao.createVertex(cat);
 
-		assertTrue(catRes.isLeft());
-	}
+        assertTrue(catRes.isLeft());
+    }
 
-	private GraphVertex createTopologyTemplate(String name) {
+    private GraphVertex createTopologyTemplate(String name) {
 
-		TopologyTemplate service = new TopologyTemplate();
-		String uniqueId = UniqueIdBuilder.buildResourceUniqueId();
-		service.setUniqueId(uniqueId);
-		service.setCreatorUserId((String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID));
-		service.getMetadata().put(JsonPresentationFields.NAME.getPresentation(), name);
-		service.getMetadata().put(JsonPresentationFields.UNIQUE_ID.getPresentation(), uniqueId);
-		service.getMetadata().put(JsonPresentationFields.VERSION.getPresentation(), "0.1");
-		service.getMetadata().put(JsonPresentationFields.TYPE.getPresentation(), ResourceTypeEnum.VF.name());
-		service.getMetadata().put(JsonPresentationFields.COMPONENT_TYPE.getPresentation(), ComponentTypeEnum.RESOURCE);
-		List<CategoryDefinition> categories = new ArrayList<>();
-		CategoryDefinition cat = new CategoryDefinition();
-		categories.add(cat);
-		cat.setName(categoryName);
-		service.setCategories(categories);
+        TopologyTemplate service = new TopologyTemplate();
+        String uniqueId = UniqueIdBuilder.buildResourceUniqueId();
+        service.setUniqueId(uniqueId);
+        service.setCreatorUserId((String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID));
+        service.getMetadata().put(JsonPresentationFields.NAME.getPresentation(), name);
+        service.getMetadata().put(JsonPresentationFields.UNIQUE_ID.getPresentation(), uniqueId);
+        service.getMetadata().put(JsonPresentationFields.VERSION.getPresentation(), "0.1");
+        service.getMetadata().put(JsonPresentationFields.TYPE.getPresentation(), ResourceTypeEnum.VF.name());
+        service.getMetadata().put(JsonPresentationFields.COMPONENT_TYPE.getPresentation(), ComponentTypeEnum.RESOURCE);
+        List<CategoryDefinition> categories = new ArrayList<>();
+        CategoryDefinition cat = new CategoryDefinition();
+        categories.add(cat);
+        cat.setName(categoryName);
+        service.setCategories(categories);
 
-		service.setComponentType(ComponentTypeEnum.SERVICE);
-		Either<TopologyTemplate, StorageOperationStatus> createRes = topologyTemplateOperation.createTopologyTemplate(service);
-		assertTrue(createRes.isLeft());
+        service.setComponentType(ComponentTypeEnum.SERVICE);
+        Either<TopologyTemplate, StorageOperationStatus> createRes = topologyTemplateOperation.createTopologyTemplate(service);
+        assertTrue(createRes.isLeft());
 
-		Either<GraphVertex, TitanOperationStatus> getNodeTyeRes = titanDao.getVertexById(createRes.left().value().getUniqueId());
-		assertTrue(getNodeTyeRes.isLeft());
+        Either<GraphVertex, TitanOperationStatus> getNodeTyeRes = titanDao.getVertexById(createRes.left().value().getUniqueId());
+        assertTrue(getNodeTyeRes.isLeft());
 
-		// serviceVertex = getNodeTyeRes.left().value();
+        // serviceVertex = getNodeTyeRes.left().value();
 
-		return getNodeTyeRes.left().value();
-	}
+        return getNodeTyeRes.left().value();
+    }
 
-	private <T extends ToscaDataDefinition> NodeType createNodeType(String nodeTypeName) {
+    private <T extends ToscaDataDefinition> NodeType createNodeType(String nodeTypeName) {
 
-		NodeType vf = new NodeType();
-		String uniqueId = UniqueIdBuilder.buildResourceUniqueId();
-		vf.setUniqueId(uniqueId);
-		vf.setCreatorUserId((String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID));
-		vf.getMetadata().put(JsonPresentationFields.NAME.getPresentation(), nodeTypeName);
-		vf.getMetadata().put(JsonPresentationFields.UNIQUE_ID.getPresentation(), uniqueId);
-		vf.getMetadata().put(JsonPresentationFields.VERSION.getPresentation(), "0.1");
-		vf.getMetadata().put(JsonPresentationFields.TYPE.getPresentation(), ResourceTypeEnum.VF.name());
-		vf.getMetadata().put(JsonPresentationFields.COMPONENT_TYPE.getPresentation(), ComponentTypeEnum.RESOURCE);
-		List<CategoryDefinition> categories = new ArrayList<>();
-		CategoryDefinition cat = new CategoryDefinition();
-		categories.add(cat);
-		cat.setName(categoryName);
-		List<SubCategoryDefinition> subCategories = new ArrayList<>();
-		SubCategoryDefinition subCat = new SubCategoryDefinition();
-		subCat.setName(subcategory);
-		subCategories.add(subCat);
-		cat.setSubcategories(subCategories);
-		vf.setCategories(categories);
+        NodeType vf = new NodeType();
+        String uniqueId = UniqueIdBuilder.buildResourceUniqueId();
+        vf.setUniqueId(uniqueId);
+        vf.setCreatorUserId((String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID));
+        vf.getMetadata().put(JsonPresentationFields.NAME.getPresentation(), nodeTypeName);
+        vf.getMetadata().put(JsonPresentationFields.UNIQUE_ID.getPresentation(), uniqueId);
+        vf.getMetadata().put(JsonPresentationFields.VERSION.getPresentation(), "0.1");
+        vf.getMetadata().put(JsonPresentationFields.TYPE.getPresentation(), ResourceTypeEnum.VF.name());
+        vf.getMetadata().put(JsonPresentationFields.COMPONENT_TYPE.getPresentation(), ComponentTypeEnum.RESOURCE);
+        List<CategoryDefinition> categories = new ArrayList<>();
+        CategoryDefinition cat = new CategoryDefinition();
+        categories.add(cat);
+        cat.setName(categoryName);
+        List<SubCategoryDefinition> subCategories = new ArrayList<>();
+        SubCategoryDefinition subCat = new SubCategoryDefinition();
+        subCat.setName(subcategory);
+        subCategories.add(subCat);
+        cat.setSubcategories(subCategories);
+        vf.setCategories(categories);
 
-		List<String> derivedFrom = new ArrayList<>();
-		derivedFrom.add("root");
-		vf.setDerivedFrom(derivedFrom);
+        List<String> derivedFrom = new ArrayList<>();
+        derivedFrom.add("root");
+        vf.setDerivedFrom(derivedFrom);
 
-		vf.setComponentType(ComponentTypeEnum.RESOURCE);
-		Either<NodeType, StorageOperationStatus> createVFRes = nodeTypeOperation.createNodeType(vf);
-		assertTrue(createVFRes.isLeft());
+        vf.setComponentType(ComponentTypeEnum.RESOURCE);
+        Either<NodeType, StorageOperationStatus> createVFRes = nodeTypeOperation.createNodeType(vf);
+        assertTrue(createVFRes.isLeft());
 
-		Either<GraphVertex, TitanOperationStatus> getNodeTyeRes = titanDao.getVertexById(createVFRes.left().value().getUniqueId());
-		assertTrue(getNodeTyeRes.isLeft());
+        Either<GraphVertex, TitanOperationStatus> getNodeTyeRes = titanDao.getVertexById(createVFRes.left().value().getUniqueId());
+        assertTrue(getNodeTyeRes.isLeft());
 
-		vfVertex = getNodeTyeRes.left().value();
+        vfVertex = getNodeTyeRes.left().value();
 
-		List<PropertyDataDefinition> addProperties = new ArrayList<>();
-		PropertyDataDefinition prop11 = new PropertyDataDefinition();
-		prop11.setName("prop11");
-		prop11.setDefaultValue("def11");
+        List<PropertyDataDefinition> addProperties = new ArrayList<>();
+        PropertyDataDefinition prop11 = new PropertyDataDefinition();
+        prop11.setName("prop11");
+        prop11.setDefaultValue("def11");
 
-		addProperties.add(prop11);
+        addProperties.add(prop11);
 
-		PropertyDataDefinition prop22 = new PropertyDataDefinition();
-		prop22.setName("prop22");
-		prop22.setDefaultValue("def22");
-		addProperties.add(prop22);
+        PropertyDataDefinition prop22 = new PropertyDataDefinition();
+        prop22.setName("prop22");
+        prop22.setDefaultValue("def22");
+        addProperties.add(prop22);
 
-		StorageOperationStatus status = nodeTypeOperation.addToscaDataToToscaElement(vfVertex, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, addProperties, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        StorageOperationStatus status = nodeTypeOperation.addToscaDataToToscaElement(vfVertex, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, addProperties, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		PropertyDataDefinition prop33 = new PropertyDataDefinition();
-		prop33.setName("prop33");
-		prop33.setDefaultValue("def33");
+        PropertyDataDefinition prop33 = new PropertyDataDefinition();
+        prop33.setName("prop33");
+        prop33.setDefaultValue("def33");
 
-		status = nodeTypeOperation.addToscaDataToToscaElement(vfVertex, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop33, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        status = nodeTypeOperation.addToscaDataToToscaElement(vfVertex, EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop33, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		PropertyDataDefinition prop44 = new PropertyDataDefinition();
-		prop44.setName("prop44");
-		prop44.setDefaultValue("def44");
+        PropertyDataDefinition prop44 = new PropertyDataDefinition();
+        prop44.setName("prop44");
+        prop44.setDefaultValue("def44");
 
-		status = nodeTypeOperation.addToscaDataToToscaElement(vfVertex.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop44, JsonPresentationFields.NAME);
-		assertTrue(status == StorageOperationStatus.OK);
+        status = nodeTypeOperation.addToscaDataToToscaElement(vfVertex.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, prop44, JsonPresentationFields.NAME);
+        assertSame(status, StorageOperationStatus.OK);
 
-		PropertyDataDefinition capProp = new PropertyDataDefinition();
-		capProp.setName("capProp");
-		capProp.setDefaultValue("capPropDef");
+        PropertyDataDefinition capProp = new PropertyDataDefinition();
+        capProp.setName("capProp");
+        capProp.setDefaultValue("capPropDef");
 
-		MapDataDefinition dataToCreate = new MapPropertiesDataDefinition();
-		dataToCreate.put("capProp", capProp);
+        MapDataDefinition dataToCreate = new MapPropertiesDataDefinition();
+        dataToCreate.put("capProp", capProp);
 
-		Map<String, MapDataDefinition> capProps = new HashMap();
-		capProps.put("capName", dataToCreate);
+        Map<String, MapDataDefinition> capProps = new HashMap();
+        capProps.put("capName", dataToCreate);
 
-		Either<GraphVertex, StorageOperationStatus> res = nodeTypeOperation.assosiateElementToData(vfVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, capProps);
+        Either<GraphVertex, StorageOperationStatus> res = nodeTypeOperation.associateElementToData(vfVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, capProps);
 
-		// exportGraphMl(titanDao.getGraph().left().value());
+        // exportGraphMl(titanDao.getGraph().left().value());
 
-		List<String> pathKeys = new ArrayList<>();
-		pathKeys.add("capName");
-		capProp.setDefaultValue("BBBB");
-		status = nodeTypeOperation.updateToscaDataDeepElementOfToscaElement(vfVertex, EdgeLabelEnum.CAPABILITIES_PROPERTIES, VertexTypeEnum.CAPABILITIES_PROPERTIES, capProp, pathKeys, JsonPresentationFields.NAME);
-		return vf;
-	}
+        List<String> pathKeys = new ArrayList<>();
+        pathKeys.add("capName");
+        capProp.setDefaultValue("BBBB");
+        status = nodeTypeOperation.updateToscaDataDeepElementOfToscaElement(vfVertex, EdgeLabelEnum.CAPABILITIES_PROPERTIES, VertexTypeEnum.CAPABILITIES_PROPERTIES, capProp, pathKeys, JsonPresentationFields.NAME);
+        return vf;
+    }
 
-	private GraphVertex createRootNodeType() {
+    private GraphVertex createRootNodeType() {
 
-		NodeType vf = new NodeType();
-		String uniqueId = UniqueIdBuilder.buildResourceUniqueId();
-		vf.setUniqueId(uniqueId);
-		vf.setComponentType(ComponentTypeEnum.RESOURCE);
-		vf.setCreatorUserId((String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID));
-		vf.getMetadata().put(JsonPresentationFields.NAME.getPresentation(), "root");
-		vf.getMetadata().put(JsonPresentationFields.UNIQUE_ID.getPresentation(), uniqueId);
-		vf.getMetadata().put(JsonPresentationFields.VERSION.getPresentation(), "1.0");
-		vf.getMetadata().put(JsonPresentationFields.TYPE.getPresentation(), ResourceTypeEnum.VFC.name());
-		vf.getMetadata().put(JsonPresentationFields.LIFECYCLE_STATE.getPresentation(), LifecycleStateEnum.CERTIFIED.name());
-		vf.getMetadata().put(JsonPresentationFields.TOSCA_RESOURCE_NAME.getPresentation(), "root");
-		vf.getMetadata().put(JsonPresentationFields.HIGHEST_VERSION.getPresentation(), true);
+        NodeType vf = new NodeType();
+        String uniqueId = UniqueIdBuilder.buildResourceUniqueId();
+        vf.setUniqueId(uniqueId);
+        vf.setComponentType(ComponentTypeEnum.RESOURCE);
+        vf.setCreatorUserId((String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID));
+        vf.getMetadata().put(JsonPresentationFields.NAME.getPresentation(), "root");
+        vf.getMetadata().put(JsonPresentationFields.UNIQUE_ID.getPresentation(), uniqueId);
+        vf.getMetadata().put(JsonPresentationFields.VERSION.getPresentation(), "1.0");
+        vf.getMetadata().put(JsonPresentationFields.TYPE.getPresentation(), ResourceTypeEnum.VFC.name());
+        vf.getMetadata().put(JsonPresentationFields.LIFECYCLE_STATE.getPresentation(), LifecycleStateEnum.CERTIFIED.name());
+        vf.getMetadata().put(JsonPresentationFields.TOSCA_RESOURCE_NAME.getPresentation(), "root");
+        vf.getMetadata().put(JsonPresentationFields.HIGHEST_VERSION.getPresentation(), true);
 
-		List<CategoryDefinition> categories = new ArrayList<>();
-		CategoryDefinition cat = new CategoryDefinition();
-		categories.add(cat);
-		cat.setName(categoryName);
-		List<SubCategoryDefinition> subCategories = new ArrayList<>();
-		SubCategoryDefinition subCat = new SubCategoryDefinition();
-		subCat.setName(subcategory);
-		subCategories.add(subCat);
-		cat.setSubcategories(subCategories);
-		vf.setCategories(categories);
+        List<CategoryDefinition> categories = new ArrayList<>();
+        CategoryDefinition cat = new CategoryDefinition();
+        categories.add(cat);
+        cat.setName(categoryName);
+        List<SubCategoryDefinition> subCategories = new ArrayList<>();
+        SubCategoryDefinition subCat = new SubCategoryDefinition();
+        subCat.setName(subcategory);
+        subCategories.add(subCat);
+        cat.setSubcategories(subCategories);
+        vf.setCategories(categories);
 
-		List<String> derivedFrom = new ArrayList<>();
-		vf.setDerivedFrom(derivedFrom);
+        List<String> derivedFrom = new ArrayList<>();
+        vf.setDerivedFrom(derivedFrom);
 
-		Map<String, PropertyDataDefinition> properties = new HashMap<>();
-		PropertyDataDefinition prop1 = new PropertyDataDefinition();
-		prop1.setName("derived1");
-		prop1.setDefaultValue("deriveddef1");
+        Map<String, PropertyDataDefinition> properties = new HashMap<>();
+        PropertyDataDefinition prop1 = new PropertyDataDefinition();
+        prop1.setName("derived1");
+        prop1.setDefaultValue("deriveddef1");
 
-		properties.put("derived1", prop1);
+        properties.put("derived1", prop1);
 
-		PropertyDataDefinition prop2 = new PropertyDataDefinition();
-		prop2.setUniqueId("derived2");
-		prop2.setName("deriveddef2");
-		properties.put("derived2", prop2);
+        PropertyDataDefinition prop2 = new PropertyDataDefinition();
+        prop2.setUniqueId("derived2");
+        prop2.setName("deriveddef2");
+        properties.put("derived2", prop2);
 
-		PropertyDataDefinition prop3 = new PropertyDataDefinition();
-		prop3.setName("derived3");
-		prop3.setDefaultValue("deriveddef3");
-		properties.put("derived3", prop3);
+        PropertyDataDefinition prop3 = new PropertyDataDefinition();
+        prop3.setName("derived3");
+        prop3.setDefaultValue("deriveddef3");
+        properties.put("derived3", prop3);
 
-		vf.setProperties(properties);
-		vf.setComponentType(ComponentTypeEnum.RESOURCE);
-		Either<NodeType, StorageOperationStatus> createVFRes = nodeTypeOperation.createNodeType(vf);
-		assertTrue(createVFRes.isLeft());
+        vf.setProperties(properties);
+        vf.setComponentType(ComponentTypeEnum.RESOURCE);
+        Either<NodeType, StorageOperationStatus> createVFRes = nodeTypeOperation.createNodeType(vf);
+        assertTrue(createVFRes.isLeft());
 
-		Either<GraphVertex, TitanOperationStatus> getNodeTyeRes = titanDao.getVertexById(createVFRes.left().value().getUniqueId());
-		assertTrue(getNodeTyeRes.isLeft());
-		return getNodeTyeRes.left().value();
-	}
+        Either<GraphVertex, TitanOperationStatus> getNodeTyeRes = titanDao.getVertexById(createVFRes.left().value().getUniqueId());
+        assertTrue(getNodeTyeRes.isLeft());
+        return getNodeTyeRes.left().value();
+    }
 
-	private void createUsers() {
+    private void createUsers() {
 
-		GraphVertex ownerV = new GraphVertex(VertexTypeEnum.USER);
-		ownerV.setUniqueId("user1");
+        GraphVertex ownerV = new GraphVertex(VertexTypeEnum.USER);
+        ownerV.setUniqueId("user1");
 
-		Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>();
-		metadataProperties.put(GraphPropertyEnum.USERID, ownerV.getUniqueId());
-		metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.USER.getName());
-		metadataProperties.put(GraphPropertyEnum.NAME, "user1");
-		ownerV.setMetadataProperties(metadataProperties);
-		ownerV.updateMetadataJsonWithCurrentMetadataProperties();
-		ownerV.setJson(new HashMap<>());
-		Either<GraphVertex, TitanOperationStatus> createUserRes = titanDao.createVertex(ownerV);
-		assertTrue(createUserRes.isLeft());
+        Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>();
+        metadataProperties.put(GraphPropertyEnum.USERID, ownerV.getUniqueId());
+        metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.USER.getName());
+        metadataProperties.put(GraphPropertyEnum.NAME, "user1");
+        ownerV.setMetadataProperties(metadataProperties);
+        ownerV.updateMetadataJsonWithCurrentMetadataProperties();
+        ownerV.setJson(new HashMap<>());
+        Either<GraphVertex, TitanOperationStatus> createUserRes = titanDao.createVertex(ownerV);
+        assertTrue(createUserRes.isLeft());
 
-		ownerVertex = createUserRes.left().value();
+        ownerVertex = createUserRes.left().value();
 
-		GraphVertex modifierV = new GraphVertex(VertexTypeEnum.USER);
-		modifierV.setUniqueId("user2");
+        GraphVertex modifierV = new GraphVertex(VertexTypeEnum.USER);
+        modifierV.setUniqueId("user2");
 
-		metadataProperties = new HashMap<>();
-		metadataProperties.put(GraphPropertyEnum.USERID, modifierV.getUniqueId());
-		metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.USER.getName());
-		metadataProperties.put(GraphPropertyEnum.NAME, "user2");
-		modifierV.setMetadataProperties(metadataProperties);
-		modifierV.updateMetadataJsonWithCurrentMetadataProperties();
-		modifierV.setJson(new HashMap<>());
-		createUserRes = titanDao.createVertex(modifierV);
-		assertTrue(createUserRes.isLeft());
+        metadataProperties = new HashMap<>();
+        metadataProperties.put(GraphPropertyEnum.USERID, modifierV.getUniqueId());
+        metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.USER.getName());
+        metadataProperties.put(GraphPropertyEnum.NAME, "user2");
+        modifierV.setMetadataProperties(metadataProperties);
+        modifierV.updateMetadataJsonWithCurrentMetadataProperties();
+        modifierV.setJson(new HashMap<>());
+        createUserRes = titanDao.createVertex(modifierV);
+        assertTrue(createUserRes.isLeft());
 
-		modifierVertex = createUserRes.left().value();
+        modifierVertex = createUserRes.left().value();
 
-		Either<GraphVertex, TitanOperationStatus> getOwnerRes = lifecycleOperation.findUser(ownerVertex.getUniqueId());
-		assertTrue(getOwnerRes.isLeft());
+        Either<GraphVertex, TitanOperationStatus> getOwnerRes = lifecycleOperation.findUser(ownerVertex.getUniqueId());
+        assertTrue(getOwnerRes.isLeft());
 
-	}
+    }
 
-	public void verifyInCatalogData(int expected, List<String> expectedIds) {
+    public void verifyInCatalogData(int expected, List<String> expectedIds) {
 
-		Either<List<CatalogComponent>, StorageOperationStatus> highestResourcesRes = topologyTemplateOperation.getElementCatalogData();
-		assertTrue(highestResourcesRes.isLeft());
-		List<CatalogComponent> highestResources = highestResourcesRes.left().value();
-		// calculate expected count value
-		assertEquals(expected, highestResources.stream().count());
-		if (expectedIds != null) {
-			highestResources.forEach(a -> assertTrue(expectedIds.contains(a.getUniqueId())));
-		}
-	}
+		Either<List<CatalogComponent>, StorageOperationStatus> highestResourcesRes = topologyTemplateOperation.getElementCatalogData(true, null);
+        assertTrue(highestResourcesRes.isLeft());
+        List<CatalogComponent> highestResources = highestResourcesRes.left().value();
+        // calculate expected count value
+        assertEquals(expected, highestResources.stream().count());
+        if (expectedIds != null) {
+            highestResources.forEach(a -> assertTrue(expectedIds.contains(a.getUniqueId())));
+        }
+    }
 
-	@After
-	public void teardown() {
-		clearGraph();
-	}
+    @After
+    public void teardown() {
+        clearGraph();
+    }
 
-	private void clearGraph() {
-		Either<TitanGraph, TitanOperationStatus> graphResult = titanDao.getGraph();
-		TitanGraph graph = graphResult.left().value();
+    private void clearGraph() {
+        Either<TitanGraph, TitanOperationStatus> graphResult = titanDao.getGraph();
+        TitanGraph graph = graphResult.left().value();
 
-		Iterable<TitanVertex> vertices = graph.query().vertices();
-		if (vertices != null) {
-			Iterator<TitanVertex> iterator = vertices.iterator();
-			while (iterator.hasNext()) {
-				TitanVertex vertex = iterator.next();
-				vertex.remove();
-			}
-		}
-		titanDao.commit();
-	}
+        Iterable<TitanVertex> vertices = graph.query().vertices();
+        if (vertices != null) {
+            Iterator<TitanVertex> iterator = vertices.iterator();
+            while (iterator.hasNext()) {
+                TitanVertex vertex = iterator.next();
+                vertex.remove();
+            }
+        }
+        titanDao.commit();
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperationTest.java
index 57689ed..5226a46 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperationTest.java
@@ -7,9 +7,9 @@
  * 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.
@@ -20,33 +20,21 @@
 
 package org.openecomp.sdc.be.model.operations.impl;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.apache.tinkerpop.gremlin.structure.Property;
-import org.apache.tinkerpop.gremlin.structure.Vertex;
+import com.thinkaurelius.titan.core.*;
+import com.thinkaurelius.titan.graphdb.relations.StandardVertexProperty;
+import com.thinkaurelius.titan.graphdb.types.system.EmptyVertex;
+import com.thinkaurelius.titan.graphdb.types.system.ImplicitKey;
+import fj.data.Either;
+import org.apache.tinkerpop.gremlin.structure.*;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.InjectMocks;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.dao.utils.UserStatusEnum;
@@ -57,173 +45,362 @@
 import org.openecomp.sdc.be.resources.data.UserData;
 import org.openecomp.sdc.common.api.UserRoleEnum;
 
-import fj.data.Either;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.*;
 
 public class UserAdminOperationTest extends ModelTestBase {
-	private static final TitanGenericDao titanGenericDao = mock(TitanGenericDao.class);
-	@InjectMocks
-	private static final UserAdminOperation userAdminOperation = new UserAdminOperation(titanGenericDao);
-	private static final String ADMIN = "admin";
+    private static final TitanGenericDao titanGenericDao = mock(TitanGenericDao.class);
+    @InjectMocks
+    private static final UserAdminOperation userAdminOperation = new UserAdminOperation(titanGenericDao);
+    private static final String ADMIN = "admin";
 
-	@BeforeClass
-	public static void setup() {
-		ModelTestBase.init();
-	}
+    @BeforeClass
+    public static void setup() {
+        ModelTestBase.init();
+    }
 
-	@Before
-	public void initMocks() {
-		MockitoAnnotations.initMocks(this);
-		Mockito.reset(titanGenericDao);
-		mockTitanUpdate();
-		mockTitanDelete();
+    @Before
+    public void initMocks() {
+        MockitoAnnotations.initMocks(this);
+        Mockito.reset(titanGenericDao);
+        mockTitanUpdate();
+        mockTitanDelete();
 
-	}
+    }
 
-	@Test
-	public void testDeActivateUserDataSuccess() {
-		UserData userData = mockTitanGet(ADMIN, UserRoleEnum.ADMIN, true);
+    @Test
+    public void testDeActivateUserDataSuccess() {
+        UserData userData = mockTitanGet(ADMIN, UserRoleEnum.ADMIN, true);
 
-		Either<User, StorageOperationStatus> eitherUser = userAdminOperation.deActivateUser(userAdminOperation.convertToUser(userData));
+        Either<User, StorageOperationStatus> eitherUser = userAdminOperation.deActivateUser(userAdminOperation.convertToUser(userData));
 
-		verify(titanGenericDao, times(1)).updateNode(Mockito.eq(userData), Mockito.eq(UserData.class));
-		verify(titanGenericDao, times(0)).deleteNode(Mockito.any(UserData.class), Mockito.eq(UserData.class));
-		assertTrue(eitherUser.isLeft());
-		User user = eitherUser.left().value();
-		assertTrue(user.getStatus() == UserStatusEnum.INACTIVE);
-	}
+        verify(titanGenericDao, times(1)).updateNode(eq(userData), eq(UserData.class));
+        verify(titanGenericDao, times(0)).deleteNode(any(UserData.class), eq(UserData.class));
+        assertTrue(eitherUser.isLeft());
+        User user = eitherUser.left().value();
+        assertSame(user.getStatus(), UserStatusEnum.INACTIVE);
+    }
 
-	@Test
-	public void testDeleteUserWithoutResources() {
-		UserData userData = mockTitanGet(ADMIN, UserRoleEnum.ADMIN, true);
+    @Test
+    public void testDeleteUserWithoutResources() {
+        UserData userData = mockTitanGet(ADMIN, UserRoleEnum.ADMIN, true);
 
-		List<Edge> edgesList = new ArrayList<Edge>();
+        List<Edge> edgesList = new ArrayList<>();
 
-		Either<List<Edge>, TitanOperationStatus> eitherResult = Either.left(edgesList);
-		when(titanGenericDao.getEdgesForNode(userData, Direction.BOTH)).thenReturn(eitherResult);
+        Either<List<Edge>, TitanOperationStatus> eitherResult = Either.left(edgesList);
+        when(titanGenericDao.getEdgesForNode(userData, Direction.BOTH)).thenReturn(eitherResult);
 
-		Either<User, ActionStatus> eitherUser = userAdminOperation.deleteUserData(ADMIN);
-		verify(titanGenericDao, times(0)).updateNode(Mockito.any(UserData.class), Mockito.eq(UserData.class));
-		verify(titanGenericDao, times(1)).deleteNode(userData, UserData.class);
-		assertTrue(eitherUser.isLeft());
+        Either<User, ActionStatus> eitherUser = userAdminOperation.deleteUserData(ADMIN);
+        verify(titanGenericDao, times(0)).updateNode(any(UserData.class), eq(UserData.class));
+        verify(titanGenericDao, times(1)).deleteNode(userData, UserData.class);
+        assertTrue(eitherUser.isLeft());
 
-	}
+    }
 
-	@Test
-	public void testDeleteUserWithResources() {
-		UserData userData = mockTitanGet(ADMIN, UserRoleEnum.ADMIN, true);
+    @Test
+    public void testDeleteUserWithResources() {
+        UserData userData = mockTitanGet(ADMIN, UserRoleEnum.ADMIN, true);
 
-		List<Edge> edgesList = new ArrayList<Edge>();
-		edgesList.add(getEmptyEdgeImpl());
+        List<Edge> edgesList = new ArrayList<>();
+        edgesList.add(getEmptyEdgeImpl());
 
-		Either<List<Edge>, TitanOperationStatus> eitherResult = Either.left(edgesList);
-		when(titanGenericDao.getEdgesForNode(userData, Direction.BOTH)).thenReturn(eitherResult);
+        Either<List<Edge>, TitanOperationStatus> eitherResult = Either.left(edgesList);
+        when(titanGenericDao.getEdgesForNode(userData, Direction.BOTH)).thenReturn(eitherResult);
 
-		Either<User, ActionStatus> eitherUser = userAdminOperation.deleteUserData(ADMIN);
-		verify(titanGenericDao, times(0)).updateNode(Mockito.any(UserData.class), Mockito.eq(UserData.class));
-		verify(titanGenericDao, times(0)).deleteNode(Mockito.any(UserData.class), Mockito.eq(UserData.class));
-		assertTrue(eitherUser.isRight());
-		assertTrue(eitherUser.right().value() == ActionStatus.USER_HAS_ACTIVE_ELEMENTS);
+        Either<User, ActionStatus> eitherUser = userAdminOperation.deleteUserData(ADMIN);
+        verify(titanGenericDao, times(0)).updateNode(any(UserData.class), eq(UserData.class));
+        verify(titanGenericDao, times(0)).deleteNode(any(UserData.class), eq(UserData.class));
+        assertTrue(eitherUser.isRight());
+        assertSame(eitherUser.right().value(), ActionStatus.USER_HAS_ACTIVE_ELEMENTS);
 
-	}
+    }
 
-	private Edge getEmptyEdgeImpl() {
-		return new Edge() {
+    @Test
+    public void getUserPendingTasks_shouldReturnNonDeleted() {
+        String userId = "abc123";
+        String userKey = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User);
+        User user = new User();
+        user.setUserId(userId);
+        TitanVertex userVertex = null;
+        TestVertex component1 = new TestVertex(null);
+        TestVertex component2 = new TestVertex(true);
+        TestVertex component3 = new TestVertex(false);
+        List<Edge> edges = new ArrayList<>();
+        Edge edge1 = new TestEdge(component1, "1");
+        Edge edge2 = new TestEdge(component2, "2");
+        Edge edge3 = new TestEdge(component3, "3");
+        edges.add(edge1);
+        edges.add(edge2);
+        edges.add(edge3);
+        when(titanGenericDao.getVertexByProperty(userKey, userId)).thenReturn(Either.left(userVertex));
+        when(titanGenericDao.getOutgoingEdgesByCriteria(any(), any(), any())).thenReturn(Either.left(edges));
+        Either<List<Edge>, StorageOperationStatus> result = userAdminOperation.getUserPendingTasksList(user, new HashMap<>());
+        assertThat(result.isLeft()).isTrue();
+        List<Edge> pendingTasks = result.left().value();
+        assertThat(pendingTasks.size()).isEqualTo(2);
+        assertThat(((TestEdge)pendingTasks.get(0)).getName()).isNotEqualTo("2");
+        assertThat(((TestEdge)pendingTasks.get(1)).getName()).isNotEqualTo("2");
+    }
 
-			@Override
-			public Object id() {
-				// TODO Auto-generated method stub
-				return null;
-			}
+    private class TestVertex implements TitanVertex {
 
-			@Override
-			public String label() {
-				// TODO Auto-generated method stub
-				return null;
-			}
+        private final Boolean isDeleted;
 
-			@Override
-			public Graph graph() {
-				// TODO Auto-generated method stub
-				return null;
-			}
+        private TestVertex(Boolean isDeleted) {
+            this.isDeleted = isDeleted;
+        }
 
-			@Override
-			public <V> Property<V> property(String key, V value) {
-				// TODO Auto-generated method stub
-				return null;
-			}
+        @Override
+        public TitanEdge addEdge(String s, Vertex vertex, Object... objects) {
+            return null;
+        }
 
-			@Override
-			public void remove() {
-				// TODO Auto-generated method stub
+        @Override
+        public <V> TitanVertexProperty<V> property(String s, V v, Object... objects) {
+            return null;
+        }
 
-			}
+        @Override
+        public <V> VertexProperty<V> property(String key) {
+            if (key.equals(GraphPropertiesDictionary.IS_DELETED.getProperty())) {
+                if (isDeleted==null)
+                    return VertexProperty.empty();
+                return new StandardVertexProperty(1, ImplicitKey.ID, new EmptyVertex(), isDeleted, (byte)1);
+            }
+            return VertexProperty.empty();
+        }
 
-			@Override
-			public Iterator<Vertex> vertices(Direction direction) {
-				// TODO Auto-generated method stub
-				return null;
-			}
+        @Override
+        public <V> TitanVertexProperty<V> property(VertexProperty.Cardinality cardinality, String s, V v, Object... objects) {
+            return null;
+        }
 
-			@Override
-			public <V> Iterator<Property<V>> properties(String... propertyKeys) {
-				// TODO Auto-generated method stub
-				return null;
-			}
+        @Override
+        public Iterator<Edge> edges(Direction direction, String... strings) {
+            return null;
+        }
 
-		};
-	}
+        @Override
+        public Iterator<Vertex> vertices(Direction direction, String... strings) {
+            return null;
+        }
 
-	private UserData mockTitanGet(String userId, UserRoleEnum role, boolean isActive) {
-		UserData userData = buildUserData(userId, role, isActive);
-		Either<UserData, TitanOperationStatus> eitherUserData = Either.left(userData);
-		when(titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class)).thenReturn(eitherUserData);
-		return userData;
-	}
+        @Override
+        public Object id() {
+            return null;
+        }
 
-	private static void mockTitanUpdate() {
-		doAnswer(new Answer<Either<UserData, TitanOperationStatus>>() {
-			public Either<UserData, TitanOperationStatus> answer(InvocationOnMock invocation) {
-				Object[] args = invocation.getArguments();
-				UserData retValue = (UserData) args[0];
-				Either<UserData, TitanOperationStatus> result = Either.left(retValue);
-				return result;
-			}
+        @Override
+        public long longId() {
+            return 0;
+        }
 
-		}).when(titanGenericDao).updateNode(Mockito.any(UserData.class), Mockito.eq(UserData.class));
-	}
+        @Override
+        public boolean hasId() {
+            return false;
+        }
 
-	private static void mockTitanDelete() {
-		doAnswer(new Answer<Either<UserData, TitanOperationStatus>>() {
-			public Either<UserData, TitanOperationStatus> answer(InvocationOnMock invocation) {
-				Object[] args = invocation.getArguments();
-				UserData retValue = (UserData) args[0];
-				Either<UserData, TitanOperationStatus> result = Either.left(retValue);
-				return result;
-			}
+        @Override
+        public String label() {
+            return null;
+        }
 
-		}).when(titanGenericDao).deleteNode(Mockito.any(UserData.class), Mockito.eq(UserData.class));
-	}
+        @Override
+        public VertexLabel vertexLabel() {
+            return null;
+        }
 
-	private void assertUserEquals(UserData expected, User actual) {
-		assertEquals(expected.getEmail(), actual.getEmail());
-		assertEquals(expected.getFirstName(), actual.getFirstName());
-		assertEquals(expected.getLastName(), actual.getLastName());
-		assertEquals(expected.getRole(), actual.getRole());
-		assertEquals(expected.getStatus(), actual.getStatus().name());
-		assertEquals(expected.getUserId(), actual.getUserId());
+        @Override
+        public TitanVertexQuery<? extends TitanVertexQuery> query() {
+            return null;
+        }
 
-	}
+        @Override
+        public boolean isModified() {
+            return false;
+        }
 
-	private static UserData buildUserData(String userId, UserRoleEnum role, boolean isActive) {
-		UserData userData = new UserData();
-		userData.setUserId(userId);
-		userData.setRole(role.getName());
-		userData.setEmail("someEmail@somePlace.com");
-		userData.setFirstName("israel");
-		userData.setLastName("israeli");
-		userData.setLastLoginTime(Instant.MIN.getEpochSecond());
-		userData.setStatus(isActive ? UserStatusEnum.ACTIVE.name() : UserStatusEnum.INACTIVE.name());
-		return userData;
-	}
+        @Override
+        public TitanTransaction graph() {
+            return null;
+        }
+
+        @Override
+        public void remove() {
+
+        }
+
+        @Override
+        public <V> V valueOrNull(PropertyKey propertyKey) {
+            return null;
+        }
+
+        @Override
+        public boolean isNew() {
+            return false;
+        }
+
+        @Override
+        public boolean isLoaded() {
+            return false;
+        }
+
+        @Override
+        public boolean isRemoved() {
+            return false;
+        }
+
+        @Override
+        public <V> Iterator<VertexProperty<V>> properties(String... strings) {
+            return null;
+        }
+    }
+
+    private class TestEdge implements Edge {
+
+        private final Vertex inVertx;
+        private final String name;
+
+        TestEdge(Vertex inVertx, String name) {
+            this.inVertx = inVertx;
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        @Override
+        public Iterator<Vertex> vertices(Direction direction) {
+            return null;
+        }
+
+        @Override
+        public Vertex inVertex() {
+            return inVertx;
+        }
+
+        @Override
+        public Object id() {
+            return null;
+        }
+
+        @Override
+        public String label() {
+            return null;
+        }
+
+        @Override
+        public Graph graph() {
+            return null;
+        }
+
+        @Override
+        public <V> Property<V> property(String s, V v) {
+            return null;
+        }
+
+        @Override
+        public void remove() {
+
+        }
+
+        @Override
+        public <V> Iterator<Property<V>> properties(String... strings) {
+            return null;
+        }
+    }
+
+    private Edge getEmptyEdgeImpl() {
+        return new Edge() {
+
+            @Override
+            public Object id() {
+                // TODO Auto-generated method stub
+                return null;
+            }
+
+            @Override
+            public String label() {
+                // TODO Auto-generated method stub
+                return null;
+            }
+
+            @Override
+            public Graph graph() {
+                // TODO Auto-generated method stub
+                return null;
+            }
+
+            @Override
+            public <V> Property<V> property(String key, V value) {
+                // TODO Auto-generated method stub
+                return null;
+            }
+
+            @Override
+            public void remove() {
+                // TODO Auto-generated method stub
+
+            }
+
+            @Override
+            public Iterator<Vertex> vertices(Direction direction) {
+                // TODO Auto-generated method stub
+                return null;
+            }
+
+            @Override
+            public <V> Iterator<Property<V>> properties(String... propertyKeys) {
+                // TODO Auto-generated method stub
+                return null;
+            }
+
+        };
+    }
+
+    private UserData mockTitanGet(String userId, UserRoleEnum role, boolean isActive) {
+        UserData userData = buildUserData(userId, role, isActive);
+        Either<UserData, TitanOperationStatus> eitherUserData = Either.left(userData);
+        when(titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class)).thenReturn(eitherUserData);
+        return userData;
+    }
+
+    private static void mockTitanUpdate() {
+        doAnswer((Answer<Either<UserData, TitanOperationStatus>>) invocation -> {
+            Object[] args = invocation.getArguments();
+            UserData retValue = (UserData) args[0];
+            return Either.left(retValue);
+        }).when(titanGenericDao).updateNode(any(UserData.class), eq(UserData.class));
+    }
+
+    private static void mockTitanDelete() {
+        doAnswer((Answer<Either<UserData, TitanOperationStatus>>) invocation -> {
+            Object[] args = invocation.getArguments();
+            UserData retValue = (UserData) args[0];
+            return Either.left(retValue);
+        }).when(titanGenericDao).deleteNode(any(UserData.class), eq(UserData.class));
+    }
+
+    private static UserData buildUserData(String userId, UserRoleEnum role, boolean isActive) {
+        UserData userData = new UserData();
+        userData.setUserId(userId);
+        userData.setRole(role.getName());
+        userData.setEmail("someEmail@somePlace.com");
+        userData.setFirstName("israel");
+        userData.setLastName("israeli");
+        userData.setLastLoginTime(Instant.MIN.getEpochSecond());
+        userData.setStatus(isActive ? UserStatusEnum.ACTIVE.name() : UserStatusEnum.INACTIVE.name());
+        return userData;
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/DataTypeValidatorTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/DataTypeValidatorTest.java
index 9237095..8700aaa 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/DataTypeValidatorTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/DataTypeValidatorTest.java
@@ -20,19 +20,10 @@
 
 package org.openecomp.sdc.be.model.operations.impl.util;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.reflect.TypeToken;
+import fj.data.Either;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.junit.Test;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
@@ -48,952 +39,951 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.reflect.TypeToken;
+import java.lang.reflect.Type;
+import java.util.*;
 
-import fj.data.Either;
+import static org.junit.Assert.*;
 
 public class DataTypeValidatorTest {
-	private static Logger log = LoggerFactory.getLogger(DataTypeValidatorTest.class.getName());
-	private static Gson gson = new Gson();
+    private static final Logger log = LoggerFactory.getLogger(DataTypeValidatorTest.class);
+    private static Gson gson = new Gson();
 
-	DataTypeValidatorConverter dataTypeValidator = DataTypeValidatorConverter.getInstance();
+    DataTypeValidatorConverter dataTypeValidator = DataTypeValidatorConverter.getInstance();
 
-	@Test
-	public void testDerivedFromPrimitiveEmptyValue() {
+    @Test
+    public void testDerivedFromPrimitiveEmptyValue() {
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		allDataTypes.put("integer", getPrimitiveDataType("integer"));
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        allDataTypes.put("integer", getPrimitiveDataType("integer"));
 
-		DataTypeDefinition fromIntegerType = buildDerivedFromIntegerType();
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate("", fromIntegerType,
-				allDataTypes);
+        DataTypeDefinition fromIntegerType = buildDerivedFromIntegerType();
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate("", fromIntegerType,
+                allDataTypes);
 
-		assertTrue("check result is valid", validate.right.booleanValue());
-		assertEquals("check value is the same as sent", null, validate.left);
+        assertTrue("check result is valid", validate.right.booleanValue());
+        assertNull("check value is the same as sent", validate.left);
 
-		validate = dataTypeValidator.validateAndUpdate(null, fromIntegerType, allDataTypes);
+        validate = dataTypeValidator.validateAndUpdate(null, fromIntegerType, allDataTypes);
 
-		assertTrue("check result is valid", validate.right.booleanValue());
-		assertEquals("check value is the same as sent", null, validate.left);
+        assertTrue("check result is valid", validate.right.booleanValue());
+        assertNull("check value is the same as sent", validate.left);
 
-		validate = dataTypeValidator.validateAndUpdate("88", fromIntegerType, allDataTypes);
+        validate = dataTypeValidator.validateAndUpdate("88", fromIntegerType, allDataTypes);
 
-		assertTrue("check result is valid", validate.right.booleanValue());
-		assertEquals("check value is the same as sent", "88", validate.left.toString());
+        assertTrue("check result is valid", validate.right.booleanValue());
+        assertEquals("check value is the same as sent", "88", validate.left.toString());
 
-	}
+    }
 
-	@Test
-	public void testCompositeWithParameterDerivedFromPrimitiveEmptyValue() {
+    @Test
+    public void testCompositeWithParameterDerivedFromPrimitiveEmptyValue() {
 
-		DataTypeDefinition derivedFromIntegerType = buildDerivedFromIntegerType();
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		allDataTypes.put("myinteger", derivedFromIntegerType);
+        DataTypeDefinition derivedFromIntegerType = buildDerivedFromIntegerType();
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        allDataTypes.put("myinteger", derivedFromIntegerType);
 
-		DataTypeDefinition personDataType = buildPersonDataType();
+        DataTypeDefinition personDataType = buildPersonDataType();
 
-		Person person = new Person("my address", 32);
-		String json = gson.toJson(person);
-		log.debug(json);
+        Person person = new Person("my address", 32);
+        String json = gson.toJson(person);
+        log.debug(json);
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, personDataType,
-				allDataTypes);
-		assertTrue("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, personDataType,
+                allDataTypes);
+        assertTrue("check valid value", validate.right.booleanValue());
 
-		person = new Person("my address", 32);
-		json = gson.toJson(person);
-		json = json.replace("32", "32a");
-		log.debug(json);
+        person = new Person("my address", 32);
+        json = gson.toJson(person);
+        json = json.replace("32", "32a");
+        log.debug(json);
 
-		validate = dataTypeValidator.validateAndUpdate(json, personDataType, allDataTypes);
-		assertFalse("check valid value", validate.right.booleanValue());
+        validate = dataTypeValidator.validateAndUpdate(json, personDataType, allDataTypes);
+        assertFalse("check valid value", validate.right.booleanValue());
 
-	}
+    }
 
-	@Test
-	public void testCompositeWithEmptyListValue() {
+    @Test
+    public void testCompositeWithEmptyListValue() {
 
-		DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
+        DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
 
-		String[] strArr = {};
-		List<String> strList = Arrays.asList(strArr);
+        String[] strArr = {};
+        List<String> strList = Arrays.asList(strArr);
 
-		// Check empty list
-		Credential credential = new Credential("protcol<br>>", 5, "token_type", "token", null, "user", true, strList);
-		City mycity = new City("myadd<br><<br>", 55);
-		credential.setMycity(mycity);
+        // Check empty list
+        Credential credential = new Credential("protcol<br>>", 5, "token_type", "token", null, "user", true, strList);
+        City mycity = new City("myadd<br><<br>", 55);
+        credential.setMycity(mycity);
 
-		String json = gson.toJson(credential);
-		log.debug(json);
+        String json = gson.toJson(credential);
+        log.debug(json);
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
-				allDataTypes);
-		assertTrue("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
+                allDataTypes);
+        assertTrue("check valid value", validate.right.booleanValue());
 
-		Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class);
-		assertEquals("check empty list", 0, credentialRes.getMylist().size());
+        Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class);
+        assertEquals("check empty list", 0, credentialRes.getMylist().size());
 
-		log.debug("Result is = {}", validate.left.toString());
+        log.debug("Result is = {}", validate.left.toString());
 
-	}
+    }
 
-	@Test
-	public void testCompositeWithListNullValue() {
-		DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
+    @Test
+    public void testCompositeWithListNullValue() {
+        DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
 
-		// Check list is NULL
-		Credential credential = new Credential("protcol<br>>", 5, "token_type", "token", null, "user", true, null);
-		City mycity = new City("myadd<br><<br>", 55);
-		credential.setMycity(mycity);
+        // Check list is NULL
+        Credential credential = new Credential("protcol<br>>", 5, "token_type", "token", null, "user", true, null);
+        City mycity = new City("myadd<br><<br>", 55);
+        credential.setMycity(mycity);
 
-		String json = gson.toJson(credential);
+        String json = gson.toJson(credential);
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
-				allDataTypes);
-		assertTrue("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
+                allDataTypes);
+        assertTrue("check valid value", validate.right.booleanValue());
 
-		Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class);
-		assertNull("check list is null", credentialRes.getMylist());
-		log.debug("Result is = {}", validate.left.toString());
+        Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class);
+        assertNull("check list is null", credentialRes.getMylist());
+        log.debug("Result is = {}", validate.left.toString());
 
-	}
+    }
 
-	@Test
-	public void testCompositeWithUserNullValue() {
-		DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
+    @Test
+    public void testCompositeWithUserNullValue() {
+        DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
 
-		// Check user is null
-		Credential credential = new Credential("protcol<br>>", 5, "token_type", "token", null, null, true, null);
-		City mycity = new City("myadd<br><<br>", 55);
-		credential.setMycity(mycity);
+        // Check user is null
+        Credential credential = new Credential("protcol<br>>", 5, "token_type", "token", null, null, true, null);
+        City mycity = new City("myadd<br><<br>", 55);
+        credential.setMycity(mycity);
 
-		String json = gson.toJson(credential);
+        String json = gson.toJson(credential);
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
-				allDataTypes);
-		assertTrue("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
+                allDataTypes);
+        assertTrue("check valid value", validate.right.booleanValue());
 
-		Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class);
-		assertNull("check list is null", credentialRes.getUser());
-		log.debug("Result is = {}", validate.left.toString());
-	}
+        Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class);
+        assertNull("check list is null", credentialRes.getUser());
+        log.debug("Result is = {}", validate.left.toString());
+    }
 
-	@Test
-	public void testCompositeWithEmptyUserValue() {
+    @Test
+    public void testCompositeWithEmptyUserValue() {
 
-		DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
+        DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
-		// Check user is empty
-		Credential credential = new Credential("protcol<br>>", 5, "token_type", "token", null, "", true, null);
-		City mycity = new City("myadd<br><<br>", 55);
-		credential.setMycity(mycity);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
+        // Check user is empty
+        Credential credential = new Credential("protcol<br>>", 5, "token_type", "token", null, "", true, null);
+        City mycity = new City("myadd<br><<br>", 55);
+        credential.setMycity(mycity);
 
-		String json = gson.toJson(credential);
-		log.debug(json);
+        String json = gson.toJson(credential);
+        log.debug(json);
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
-				allDataTypes);
-		assertTrue("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
+                allDataTypes);
+        assertTrue("check valid value", validate.right.booleanValue());
 
-		Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class);
-		assertNotNull("check list is not null", credentialRes.getUser());
-		assertEquals("check user is empty", "", credentialRes.getUser());
-		log.debug("Result is = {}", validate.left.toString());
+        Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class);
+        assertNotNull("check list is not null", credentialRes.getUser());
+        assertEquals("check user is empty", "", credentialRes.getUser());
+        log.debug("Result is = {}", validate.left.toString());
 
-	}
+    }
 
-	@Test
-	public void testCompositeWithSumNullValue() {
-		DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
+    @Test
+    public void testCompositeWithSumNullValue() {
+        DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
 
-		// Check user is null
-		Credential credential = new Credential("protcol<br>>", null, "token_type", "token", null, null, true, null);
-		City mycity = new City("myadd<br><<br>", 55);
-		credential.setMycity(mycity);
+        // Check user is null
+        Credential credential = new Credential("protcol<br>>", null, "token_type", "token", null, null, true, null);
+        City mycity = new City("myadd<br><<br>", 55);
+        credential.setMycity(mycity);
 
-		String json = gson.toJson(credential);
+        String json = gson.toJson(credential);
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
-				allDataTypes);
-		assertTrue("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
+                allDataTypes);
+        assertTrue("check valid value", validate.right.booleanValue());
 
-		Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class);
-		assertNull("check list is null", credentialRes.getSum());
-		log.debug("Result is = {}", validate.left.toString());
-	}
+        Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class);
+        assertNull("check list is null", credentialRes.getSum());
+        log.debug("Result is = {}", validate.left.toString());
+    }
 
-	@Test
-	public void testInvalidJson() {
-		DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
+    @Test
+    public void testInvalidJson() {
+        DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
 
-		// Check user is null
-		Credential credential = new Credential("protcol<br>>", null, "token_type", "token", null, null, true, null);
-		City mycity = new City("myadd<br><<br>", 55);
-		credential.setMycity(mycity);
+        // Check user is null
+        Credential credential = new Credential("protcol<br>>", null, "token_type", "token", null, null, true, null);
+        City mycity = new City("myadd<br><<br>", 55);
+        credential.setMycity(mycity);
 
-		String json = gson.toJson(credential);
+        String json = gson.toJson(credential);
 
-		json += "fdfd";
+        json += "fdfd";
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
-				allDataTypes);
-		assertFalse("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
+                allDataTypes);
+        assertFalse("check valid value", validate.right.booleanValue());
 
-	}
+    }
 
-	@Test
-	public void testInvalidInnerValue() {
+    @Test
+    public void testInvalidInnerValue() {
 
-		DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
+        DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
 
-		// Check user is null
-		Credential credential = new Credential("protcol<br>>", null, "token_type", "token", null, null, true, null);
-		City mycity = new City("myadd<br><<br>", 55);
-		credential.setMycity(mycity);
+        // Check user is null
+        Credential credential = new Credential("protcol<br>>", null, "token_type", "token", null, null, true, null);
+        City mycity = new City("myadd<br><<br>", 55);
+        credential.setMycity(mycity);
 
-		String json = gson.toJson(credential);
+        String json = gson.toJson(credential);
 
-		json = json.replace("55", "a55b");
+        json = json.replace("55", "a55b");
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
-				allDataTypes);
-		assertFalse("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
+                allDataTypes);
+        assertFalse("check valid value", validate.right.booleanValue());
 
-	}
+    }
 
-	@Test
-	public void testInvalidInnerJson() {
+    @Test
+    public void testInvalidInnerJson() {
 
-		DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
+        DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
 
-		// Check user is null
-		Credential credential = new Credential("protcol<br>>", null, "token_type", "token", null, null, true, null);
-		City mycity = new City("", null);
+        // Check user is null
+        Credential credential = new Credential("protcol<br>>", null, "token_type", "token", null, null, true, null);
+        City mycity = new City("", null);
 
-		credential.setMycity(mycity);
+        credential.setMycity(mycity);
 
-		String json = gson.toJson(credential);
+        String json = gson.toJson(credential);
 
-		json = json.replace("{\"address\":\"\"}", "scalar");
+        json = json.replace("{\"address\":\"\"}", "scalar");
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
-				allDataTypes);
-		assertFalse("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
+                allDataTypes);
+        assertFalse("check valid value", validate.right.booleanValue());
 
-	}
+    }
 
-	@Test
-	public void testInvalidPropertyJson() {
+    @Test
+    public void testInvalidPropertyJson() {
 
-		DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
+        DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
 
-		// Check user is null
-		Credential credential = new Credential("protcol<br>>", null, "token_type", "token", null, null, true, null);
-		City mycity = new City("myadd<br><<br>", 55);
-		credential.setMycity(mycity);
+        // Check user is null
+        Credential credential = new Credential("protcol<br>>", null, "token_type", "token", null, null, true, null);
+        City mycity = new City("myadd<br><<br>", 55);
+        credential.setMycity(mycity);
 
-		String json = gson.toJson(credential);
+        String json = gson.toJson(credential);
 
-		json = json.replace("55", "a55b");
+        json = json.replace("55", "a55b");
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
-				allDataTypes);
-		assertFalse("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
+                allDataTypes);
+        assertFalse("check valid value", validate.right.booleanValue());
 
-	}
+    }
 
-	@Test
-	public void testCompositeDataTypeWithInternalComposite() {
+    @Test
+    public void testCompositeDataTypeWithInternalComposite() {
 
-		DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
+        DataTypeDefinition dataTypeDefinition = buildCredentialDataType();
 
-		String[] strArr = { "aaa", "bbb", "c<br>dcc" };
-		List<String> strList = Arrays.asList(strArr);
+        String[] strArr = { "aaa", "bbb", "c<br>dcc" };
+        List<String> strList = Arrays.asList(strArr);
 
-		Credential credential = new Credential("protcol<br>>", 5, "token_type", "token", null, "user", true, strList);
-		City mycity = new City("myadd<br><<br>", 55);
-		credential.setMycity(mycity);
+        Credential credential = new Credential("protcol<br>>", 5, "token_type", "token", null, "user", true, strList);
+        City mycity = new City("myadd<br><<br>", 55);
+        credential.setMycity(mycity);
 
-		String json = gson.toJson(credential);
+        String json = gson.toJson(credential);
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
 
-		ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
-				allDataTypes);
-		assertTrue("check valid value", validate.right.booleanValue());
+        ImmutablePair<JsonElement, Boolean> validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition,
+                allDataTypes);
+        assertTrue("check valid value", validate.right.booleanValue());
 
-		log.debug("Result is = {}", validate.left.toString());
+        log.debug("Result is = {}", validate.left.toString());
 
-	}
+    }
 
-	@Test
-	public void testMapValidator() {
+    @Test
+    public void testMapValidator() {
 
-		MapValidator validator = new MapValidator();
-		Gson gson = new Gson();
-		// Happy Scenarios
-		// 1 - Map<String,Integer> check OK
-		Map<String, Integer> map_1 = new HashMap<>();
-		map_1.put("key1", 2);
-		map_1.put("key2", 3);
-		String value = gson.toJson(map_1);
-		String innerType = "integer";
-		assertTrue("Test Map validation with inner integer type", validator.isValid(value, innerType, null));
+        MapValidator validator = new MapValidator();
+        Gson gson = new Gson();
+        // Happy Scenarios
+        // 1 - Map<String,Integer> check OK
+        Map<String, Integer> map_1 = new HashMap<>();
+        map_1.put("key1", 2);
+        map_1.put("key2", 3);
+        String value = gson.toJson(map_1);
+        String innerType = "integer";
+        assertTrue("Test Map validation with inner integer type", validator.isValid(value, innerType, null));
 
-		// 2 - Map<String,Boolean> check OK
-		Map<String, Boolean> map_2 = new HashMap<>();
-		map_2.put("key1", true);
-		map_2.put("key2", false);
-		value = gson.toJson(map_2);
-		innerType = "boolean";
-		assertTrue("Test Map validation with inner boolean type", validator.isValid(value, innerType, null));
+        // 2 - Map<String,Boolean> check OK
+        Map<String, Boolean> map_2 = new HashMap<>();
+        map_2.put("key1", true);
+        map_2.put("key2", false);
+        value = gson.toJson(map_2);
+        innerType = "boolean";
+        assertTrue("Test Map validation with inner boolean type", validator.isValid(value, innerType, null));
 
-		// 3 - give integer with quotes
-		innerType = "integer";
-		value = "{\"key1\":\"5\",\"key2\":\"7\"}";
-		assertTrue("Test Map validation with inner integer type, but qouted values",
-				validator.isValid(value, innerType, null));
+        // 3 - give integer with quotes
+        innerType = "integer";
+        value = "{\"key1\":\"5\",\"key2\":\"7\"}";
+        assertTrue("Test Map validation with inner integer type, but qouted values",
+                validator.isValid(value, innerType, null));
 
-		// 4 - empty default value
-		innerType = "float";
-		value = "";
-		assertTrue("Test Map validation with inner float type", validator.isValid(value, innerType, null));
+        // 4 - empty default value
+        innerType = "float";
+        value = "";
+        assertTrue("Test Map validation with inner float type", validator.isValid(value, innerType, null));
 
-		// Faulty Scenarios
-		// 5 - mismatch in data type
-		value = gson.toJson(map_1);
-		innerType = "boolean";
-		assertFalse("Test Map faulty validation with inner boolean type", validator.isValid(value, innerType, null));
-		// 6 - mismatch in data type
-		value = gson.toJson(map_2);
-		innerType = "integer";
-		assertFalse("Test Map faulty validation with inner integer type", validator.isValid(value, innerType, null));
+        // Faulty Scenarios
+        // 5 - mismatch in data type
+        value = gson.toJson(map_1);
+        innerType = "boolean";
+        assertFalse("Test Map faulty validation with inner boolean type", validator.isValid(value, innerType, null));
+        // 6 - mismatch in data type
+        value = gson.toJson(map_2);
+        innerType = "integer";
+        assertFalse("Test Map faulty validation with inner integer type", validator.isValid(value, innerType, null));
 
-	}
+    }
 
-	@Test
-	public void testMapConverter() {
+    @Test
+    public void testMapConverter() {
 
-		MapConverter converter = new MapConverter();
-		Gson gson = new Gson();
-		// Happy Scenarios
-		Map<String, String> map_1 = new HashMap<>();
-		Map<String, String> resMap_1 = new HashMap<>();
+        MapConverter converter = new MapConverter();
+        Gson gson = new Gson();
+        // Happy Scenarios
+        Map<String, String> map_1 = new HashMap<>();
+        Map<String, String> resMap_1 = new HashMap<>();
 
-		// 1 - check Spaces eliminated + html square brackets eliminated
-		map_1.put("key1", "<b>test</b>");
-		map_1.put("key2", "        test");
-		resMap_1.put("key1", "test");
-		resMap_1.put("key2", " test");
-		String value = gson.toJson(map_1);
-		String expectedVal = gson.toJson(resMap_1);
-		String innerType = "string";
-		assertEquals("Test Map validation with inner string type", expectedVal,
-				converter.convert(value, innerType, null));
+        // 1 - check Spaces eliminated + html square brackets eliminated
+        map_1.put("key1", "<b>test</b>");
+        map_1.put("key2", "        test");
+        resMap_1.put("key1", "test");
+        resMap_1.put("key2", " test");
+        String value = gson.toJson(map_1);
+        String expectedVal = gson.toJson(resMap_1);
+        String innerType = "string";
+        assertEquals("Test Map validation with inner string type", expectedVal,
+                converter.convert(value, innerType, null));
 
-		// 2 - float converter
-		innerType = "float";
-		value = "{\"key1\":0.4545,\"key2\":0.2f}";
-		expectedVal = "{\"key1\":0.4545,\"key2\":0.2}";
-		assertEquals("Test Map validation with inner float type", expectedVal,
-				converter.convert(value, innerType, null));
+        // 2 - float converter
+        innerType = "float";
+        value = "{\"key1\":0.4545,\"key2\":0.2f}";
+        expectedVal = "{\"key1\":0.4545,\"key2\":0.2}";
+        assertEquals("Test Map validation with inner float type", expectedVal,
+                converter.convert(value, innerType, null));
 
-		// 3 - check default empty value converter
-		innerType = "float";
-		value = "";
-		expectedVal = "";
-		assertEquals("Test Map validation with inner float type", expectedVal,
-				converter.convert(value, innerType, null));
+        // 3 - check default empty value converter
+        innerType = "float";
+        value = "";
+        expectedVal = "";
+        assertEquals("Test Map validation with inner float type", expectedVal,
+                converter.convert(value, innerType, null));
 
-		// 4 - invalid json
-		// 3 - check default empty value converter
-		innerType = "float";
-		value = "{1345234556@#(";
-		expectedVal = null;
-		assertEquals("Test Map validation with inner float type", expectedVal,
-				converter.convert(value, innerType, null));
+        // 4 - invalid json
+        // 3 - check default empty value converter
+        innerType = "float";
+        value = "{1345234556@#(";
+        expectedVal = null;
+        assertEquals("Test Map validation with inner float type", expectedVal,
+                converter.convert(value, innerType, null));
 
-	}
+    }
 
-	@Test
-	public void testCompositeDataTypeWithMapComposite() {
+    @Test
+    public void testCompositeDataTypeWithMapComposite() {
 
-		DataTypeDefinition fileDataTypeDefinition = buildFileDataType();
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
+        DataTypeDefinition fileDataTypeDefinition = buildFileDataType();
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
 
-		MyFile myFile = new MyFile();
-		myFile.setAge(88);
-		Map<String, City> attributes = new HashMap<>();
-		attributes.put("key1", new City("address1<br>", 11));
-		attributes.put("key2", new City("address2<br>", 22));
-		myFile.setAttributes(attributes);
+        MyFile myFile = new MyFile();
+        myFile.setAge(88);
+        Map<String, City> attributes = new HashMap<>();
+        attributes.put("key1", new City("address1<br>", 11));
+        attributes.put("key2", new City("address2<br>", 22));
+        myFile.setAttributes(attributes);
 
-		String str = gson.toJson(myFile);
-		log.debug(str);
+        String str = gson.toJson(myFile);
+        log.debug(str);
 
-		ImmutablePair<JsonElement, Boolean> convert = dataTypeValidator.validateAndUpdate(str, fileDataTypeDefinition,
-				allDataTypes);
+        ImmutablePair<JsonElement, Boolean> convert = dataTypeValidator.validateAndUpdate(str, fileDataTypeDefinition,
+                allDataTypes);
 
-		assertTrue("check map converter succeed", convert.right);
+        assertTrue("check map converter succeed", convert.right);
 
-		JsonElement convertedValue = convert.left;
+        JsonElement convertedValue = convert.left;
 
-		log.debug("{}", convertedValue);
-		MyFile fromJson = gson.fromJson(convertedValue, MyFile.class);
+        log.debug("{}", convertedValue);
+        MyFile fromJson = gson.fromJson(convertedValue, MyFile.class);
 
-		assertEquals("check age", 88, fromJson.getAge().intValue());
-		assertEquals("check address 1", "address1", fromJson.getAttributes().get("key1").getAddress());
-		assertEquals("check address 2", "address2", fromJson.getAttributes().get("key2").getAddress());
+        assertEquals("check age", 88, fromJson.getAge().intValue());
+        assertEquals("check address 1", "address1", fromJson.getAttributes().get("key1").getAddress());
+        assertEquals("check address 2", "address2", fromJson.getAttributes().get("key2").getAddress());
 
-	}
+    }
 
-	@Test
-	public void testMapConverterWithComplexInnerType() {
+    @Test
+    public void testMapConverterWithComplexInnerType() {
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition credentialDataTypeDefinition = buildCredentialDataType();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
-		allDataTypes.put("credential", credentialDataTypeDefinition);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition credentialDataTypeDefinition = buildCredentialDataType();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
+        allDataTypes.put("credential", credentialDataTypeDefinition);
 
-		Gson gson = new Gson();
-		// Happy Scenarios
-		Map<String, Object> map_1 = new HashMap<>();
+        Gson gson = new Gson();
+        // Happy Scenarios
+        Map<String, Object> map_1 = new HashMap<>();
 
-		// 1 - check Spaces eliminated + html square brackets eliminated
+        // 1 - check Spaces eliminated + html square brackets eliminated
 
-		String[] strArr = { "aaa", "bbb", "c<br>dcc" };
-		List<String> strList = Arrays.asList(strArr);
-		Credential credential1 = new Credential("protocol;:,.\"<br>>", 5, "token_type", "token", null, "user", true,
-				strList);
-		City mycity1 = new City("myadd<br><<br>", 55);
-		credential1.setMycity(mycity1);
+        String[] strArr = { "aaa", "bbb", "c<br>dcc" };
+        List<String> strList = Arrays.asList(strArr);
+        Credential credential1 = new Credential("protocol;:,.\"<br>>", 5, "token_type", "token", null, "user", true,
+                strList);
+        City mycity1 = new City("myadd<br><<br>", 55);
+        credential1.setMycity(mycity1);
 
-		Credential credential2 = new Credential("protocol;:,.\"<br>>", 5, "token_type", "token", null, "user", true,
-				strList);
-		City mycity2 = new City("myadd<br><<br>", 66);
-		credential2.setMycity(mycity2);
+        Credential credential2 = new Credential("protocol;:,.\"<br>>", 5, "token_type", "token", null, "user", true,
+                strList);
+        City mycity2 = new City("myadd<br><<br>", 66);
+        credential2.setMycity(mycity2);
 
-		map_1.put("key1", credential1);
-		map_1.put("key2", credential2);
+        map_1.put("key1", credential1);
+        map_1.put("key2", credential2);
 
-		String str = gson.toJson(map_1);
-		log.debug(str);
+        String str = gson.toJson(map_1);
+        log.debug(str);
 
-		MapConverter mapConverter = new MapConverter();
-		Either<String, Boolean> convert = mapConverter.convertWithErrorResult(str, "credential", allDataTypes);
+        MapConverter mapConverter = new MapConverter();
+        Either<String, Boolean> convert = mapConverter.convertWithErrorResult(str, "credential", allDataTypes);
 
-		assertTrue("check map converter succeed", convert.isLeft());
+        assertTrue("check map converter succeed", convert.isLeft());
 
-		String convertedValue = convert.left().value();
+        String convertedValue = convert.left().value();
 
-		Type type = new TypeToken<Map<String, Credential>>() {
-		}.getType();
+        Type type = new TypeToken<Map<String, Credential>>() {
+        }.getType();
 
-		Map<String, Credential> fromJson = gson.fromJson(convertedValue, type);
+        Map<String, Credential> fromJson = gson.fromJson(convertedValue, type);
 
-		Credential actualCredential1 = fromJson.get("key1");
-		assertEquals("check sum", 5, actualCredential1.getSum().intValue());
-		assertEquals("check protocol", "protocol;:,.\">", actualCredential1.getProtocol());
-		String[] convertedStrArr = { "aaa", "bbb", "cdcc" };
-		List<String> convertedStrList = Arrays.asList(convertedStrArr);
-		assertEquals("check list", convertedStrList, actualCredential1.getMylist());
+        Credential actualCredential1 = fromJson.get("key1");
+        assertEquals("check sum", 5, actualCredential1.getSum().intValue());
+        assertEquals("check protocol", "protocol;:,.\">", actualCredential1.getProtocol());
+        String[] convertedStrArr = { "aaa", "bbb", "cdcc" };
+        List<String> convertedStrList = Arrays.asList(convertedStrArr);
+        assertEquals("check list", convertedStrList, actualCredential1.getMylist());
 
-		assertEquals("check city address", "myadd<", actualCredential1.getMycity().getAddress());
-		assertEquals("check city address", 55, actualCredential1.getMycity().getAge().intValue());
+        assertEquals("check city address", "myadd<", actualCredential1.getMycity().getAddress());
+        assertEquals("check city address", 55, actualCredential1.getMycity().getAge().intValue());
 
-		Credential actualCredential2 = fromJson.get("key2");
-		assertEquals("check city address", 66, actualCredential2.getMycity().getAge().intValue());
+        Credential actualCredential2 = fromJson.get("key2");
+        assertEquals("check city address", 66, actualCredential2.getMycity().getAge().intValue());
 
-	}
+    }
 
-	@Test
-	public void testListConverterWithComplexInnerType() {
+    @Test
+    public void testListConverterWithComplexInnerType() {
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition credentialDataTypeDefinition = buildCredentialDataType();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
-		allDataTypes.put("credential", credentialDataTypeDefinition);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition credentialDataTypeDefinition = buildCredentialDataType();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
+        allDataTypes.put("credential", credentialDataTypeDefinition);
 
-		Gson gson = new Gson();
+        Gson gson = new Gson();
 
-		List<Object> list = buildListOf2CredentialObjects();
+        List<Object> list = buildListOf2CredentialObjects();
 
-		String str = gson.toJson(list);
-		log.debug(str);
+        String str = gson.toJson(list);
+        log.debug(str);
 
-		ListConverter listConverter = new ListConverter();
+        ListConverter listConverter = new ListConverter();
 
-		Either<String, Boolean> convert = listConverter.convertWithErrorResult(str, "credential", allDataTypes);
+        Either<String, Boolean> convert = listConverter.convertWithErrorResult(str, "credential", allDataTypes);
 
-		assertTrue("check map converter succeed", convert.isLeft());
+        assertTrue("check map converter succeed", convert.isLeft());
 
-		String convertedValue = convert.left().value();
+        String convertedValue = convert.left().value();
 
-		validateListOfCredential(gson, convertedValue);
+        validateListOfCredential(gson, convertedValue);
 
-		list.add(null);
+        list.add(null);
 
-		str = gson.toJson(list);
-		log.debug(str);
+        str = gson.toJson(list);
+        log.debug(str);
 
-		convert = listConverter.convertWithErrorResult(str, "credential", allDataTypes);
+        convert = listConverter.convertWithErrorResult(str, "credential", allDataTypes);
 
-		assertTrue("check map converter succeed", convert.isLeft());
+        assertTrue("check map converter succeed", convert.isLeft());
 
-		validateListOfCredential(gson, convertedValue);
-	}
+        validateListOfCredential(gson, convertedValue);
+    }
 
-	@Test
-	public void testListValidatorWithComplexInnerType() {
+    @Test
+    public void testListValidatorWithComplexInnerType() {
 
-		Map<String, DataTypeDefinition> allDataTypes = new HashMap<String, DataTypeDefinition>();
-		DataTypeDefinition credentialDataTypeDefinition = buildCredentialDataType();
-		DataTypeDefinition cityDataType = buildCityDataType();
-		allDataTypes.put("city", cityDataType);
-		allDataTypes.put("credential", credentialDataTypeDefinition);
+        Map<String, DataTypeDefinition> allDataTypes = new HashMap<>();
+        DataTypeDefinition credentialDataTypeDefinition = buildCredentialDataType();
+        DataTypeDefinition cityDataType = buildCityDataType();
+        allDataTypes.put("city", cityDataType);
+        allDataTypes.put("credential", credentialDataTypeDefinition);
 
-		Gson gson = new Gson();
-		// Happy Scenarios
-		List<Object> list = buildListOf2CredentialObjects();
+        Gson gson = new Gson();
+        // Happy Scenarios
+        List<Object> list = buildListOf2CredentialObjects();
 
-		String str = gson.toJson(list);
-		log.debug(str);
+        String str = gson.toJson(list);
+        log.debug(str);
 
-		ListValidator listValidator = new ListValidator();
+        ListValidator listValidator = new ListValidator();
 
-		boolean isValid = listValidator.isValid(str, "credential", allDataTypes);
+        boolean isValid = listValidator.isValid(str, "credential", allDataTypes);
 
-		assertTrue("check valid value", isValid);
+        assertTrue("check valid value", isValid);
 
-		String badStr = str.replace("protocol", "protocol1");
+        String badStr = str.replace("protocol", "protocol1");
 
-		isValid = listValidator.isValid(badStr, "credential", allDataTypes);
+        isValid = listValidator.isValid(badStr, "credential", allDataTypes);
 
-		assertFalse("check valid value", isValid);
+        assertFalse("check valid value", isValid);
 
-		badStr = str.replace("55", "\"aa\"");
+        badStr = str.replace("55", "\"aa\"");
 
-		isValid = listValidator.isValid(badStr, "credential", allDataTypes);
+        isValid = listValidator.isValid(badStr, "credential", allDataTypes);
 
-		assertFalse("check valid value", isValid);
+        assertFalse("check valid value", isValid);
 
-	}
+    }
 
-	private List<Object> buildListOf2CredentialObjects() {
-		List<Object> list = new ArrayList<>();
+    private List<Object> buildListOf2CredentialObjects() {
+        List<Object> list = new ArrayList<>();
 
-		String[] strArr = { "aaa", "bbb", "c<br>dcc" };
-		List<String> strList = Arrays.asList(strArr);
-		Credential credential1 = new Credential("protocol.,\":;<br>>", 5, "token_type", "token", null, "user", true,
-				strList);
-		City mycity1 = new City("myadd<br><<br>", 55);
-		credential1.setMycity(mycity1);
+        String[] strArr = { "aaa", "bbb", "c<br>dcc" };
+        List<String> strList = Arrays.asList(strArr);
+        Credential credential1 = new Credential("protocol.,\":;<br>>", 5, "token_type", "token", null, "user", true,
+                strList);
+        City mycity1 = new City("myadd<br><<br>", 55);
+        credential1.setMycity(mycity1);
 
-		Credential credential2 = new Credential("protocol.,\":;<br>>", 5, "token_type", "token", null, "user", true,
-				strList);
-		City mycity2 = new City("myadd<br><<br>", 66);
-		credential2.setMycity(mycity2);
+        Credential credential2 = new Credential("protocol.,\":;<br>>", 5, "token_type", "token", null, "user", true,
+                strList);
+        City mycity2 = new City("myadd<br><<br>", 66);
+        credential2.setMycity(mycity2);
 
-		list.add(credential1);
-		list.add(credential2);
-		return list;
-	}
+        list.add(credential1);
+        list.add(credential2);
+        return list;
+    }
 
-	private void validateListOfCredential(Gson gson, String convertedValue) {
+    private void validateListOfCredential(Gson gson, String convertedValue) {
 
-		log.debug(convertedValue);
-		Type type = new TypeToken<List<Credential>>() {
-		}.getType();
+        log.debug(convertedValue);
+        Type type = new TypeToken<List<Credential>>() {
+        }.getType();
 
-		List<Credential> fromJson = gson.fromJson(convertedValue, type);
+        List<Credential> fromJson = gson.fromJson(convertedValue, type);
 
-		assertEquals("check list size", 2, fromJson.size());
+        assertEquals("check list size", 2, fromJson.size());
 
-		// Credential actualCredential1 = gson.fromJson(list.get(0).toString(),
-		// Credential.class);
-		Credential actualCredential1 = fromJson.get(0);
-		assertEquals("check sum", 5, actualCredential1.getSum().intValue());
-		assertEquals("check protocol", "protocol.,\":;>", actualCredential1.getProtocol());
-		String[] convertedStrArr = { "aaa", "bbb", "cdcc" };
-		List<String> convertedStrList = Arrays.asList(convertedStrArr);
-		assertEquals("check list", convertedStrList, actualCredential1.getMylist());
+        // Credential actualCredential1 = gson.fromJson(list.get(0).toString(),
+        // Credential.class);
+        Credential actualCredential1 = fromJson.get(0);
+        assertEquals("check sum", 5, actualCredential1.getSum().intValue());
+        assertEquals("check protocol", "protocol.,\":;>", actualCredential1.getProtocol());
+        String[] convertedStrArr = { "aaa", "bbb", "cdcc" };
+        List<String> convertedStrList = Arrays.asList(convertedStrArr);
+        assertEquals("check list", convertedStrList, actualCredential1.getMylist());
 
-		assertEquals("check city address", "myadd<", actualCredential1.getMycity().getAddress());
-		assertEquals("check city address", 55, actualCredential1.getMycity().getAge().intValue());
+        assertEquals("check city address", "myadd<", actualCredential1.getMycity().getAddress());
+        assertEquals("check city address", 55, actualCredential1.getMycity().getAge().intValue());
 
-		// Credential actualCredential2 = gson.fromJson(list.get(1).toString(),
-		// Credential.class);
-		Credential actualCredential2 = fromJson.get(1);
-		assertEquals("check city address", 66, actualCredential2.getMycity().getAge().intValue());
-	}
+        // Credential actualCredential2 = gson.fromJson(list.get(1).toString(),
+        // Credential.class);
+        Credential actualCredential2 = fromJson.get(1);
+        assertEquals("check city address", 66, actualCredential2.getMycity().getAge().intValue());
+    }
 
-	private DataTypeDefinition buildCredentialDataType() {
-		DataTypeDefinition dataTypeDefinition = new DataTypeDefinition();
-		dataTypeDefinition.setName("datatype.1");
-		List<PropertyDefinition> properties = new ArrayList<>();
-		PropertyDefinition propertyDefinition1 = new PropertyDefinition();
-		propertyDefinition1.setName("sum");
-		propertyDefinition1.setType(ToscaPropertyType.INTEGER.getType());
-		PropertyDefinition propertyDefinition2 = new PropertyDefinition();
-		propertyDefinition2.setName("protocol");
-		propertyDefinition2.setType(ToscaPropertyType.STRING.getType());
-		PropertyDefinition propertyDefinition3 = new PropertyDefinition();
-		propertyDefinition3.setName("token_type");
-		propertyDefinition3.setType(ToscaPropertyType.STRING.getType());
-		PropertyDefinition propertyDefinition4 = new PropertyDefinition();
-		propertyDefinition4.setName("token");
-		propertyDefinition4.setType(ToscaPropertyType.STRING.getType());
-		PropertyDefinition propertyDefinition5 = new PropertyDefinition();
-		propertyDefinition5.setName("keys");
-		propertyDefinition5.setType(ToscaPropertyType.MAP.getType());
-		PropertyDefinition propertyDefinition6 = new PropertyDefinition();
-		propertyDefinition6.setName("mylist");
-		propertyDefinition6.setType(ToscaPropertyType.LIST.getType());
-		SchemaDefinition entrySchema = new SchemaDefinition();
-		PropertyDataDefinition property = new PropertyDataDefinition();
-		property.setType("string");
-		entrySchema.setProperty(property);
-		propertyDefinition6.setSchema(entrySchema);
-		PropertyDefinition propertyDefinition7 = new PropertyDefinition();
-		propertyDefinition7.setName("user");
-		propertyDefinition7.setType(ToscaPropertyType.STRING.getType());
-		PropertyDefinition propertyDefinition8 = new PropertyDefinition();
-		propertyDefinition8.setName("isMandatory");
-		propertyDefinition8.setType(ToscaPropertyType.BOOLEAN.getType());
+    private DataTypeDefinition buildCredentialDataType() {
+        DataTypeDefinition dataTypeDefinition = new DataTypeDefinition();
+        dataTypeDefinition.setName("datatype.1");
+        List<PropertyDefinition> properties = new ArrayList<>();
+        PropertyDefinition propertyDefinition1 = new PropertyDefinition();
+        propertyDefinition1.setName("sum");
+        propertyDefinition1.setType(ToscaPropertyType.INTEGER.getType());
+        PropertyDefinition propertyDefinition2 = new PropertyDefinition();
+        propertyDefinition2.setName("protocol");
+        propertyDefinition2.setType(ToscaPropertyType.STRING.getType());
+        PropertyDefinition propertyDefinition3 = new PropertyDefinition();
+        propertyDefinition3.setName("token_type");
+        propertyDefinition3.setType(ToscaPropertyType.STRING.getType());
+        PropertyDefinition propertyDefinition4 = new PropertyDefinition();
+        propertyDefinition4.setName("token");
+        propertyDefinition4.setType(ToscaPropertyType.STRING.getType());
+        PropertyDefinition propertyDefinition5 = new PropertyDefinition();
+        propertyDefinition5.setName("keys");
+        propertyDefinition5.setType(ToscaPropertyType.MAP.getType());
+        PropertyDefinition propertyDefinition6 = new PropertyDefinition();
+        propertyDefinition6.setName("mylist");
+        propertyDefinition6.setType(ToscaPropertyType.LIST.getType());
+        SchemaDefinition entrySchema = new SchemaDefinition();
+        PropertyDataDefinition property = new PropertyDataDefinition();
+        property.setType("string");
+        entrySchema.setProperty(property);
+        propertyDefinition6.setSchema(entrySchema);
+        PropertyDefinition propertyDefinition7 = new PropertyDefinition();
+        propertyDefinition7.setName("user");
+        propertyDefinition7.setType(ToscaPropertyType.STRING.getType());
+        PropertyDefinition propertyDefinition8 = new PropertyDefinition();
+        propertyDefinition8.setName("isMandatory");
+        propertyDefinition8.setType(ToscaPropertyType.BOOLEAN.getType());
 
-		PropertyDefinition propertyDefinition9 = new PropertyDefinition();
-		propertyDefinition9.setName("mycity");
-		propertyDefinition9.setType("city");
+        PropertyDefinition propertyDefinition9 = new PropertyDefinition();
+        propertyDefinition9.setName("mycity");
+        propertyDefinition9.setType("city");
 
-		properties.add(propertyDefinition1);
-		properties.add(propertyDefinition2);
-		properties.add(propertyDefinition3);
-		properties.add(propertyDefinition4);
-		properties.add(propertyDefinition5);
-		properties.add(propertyDefinition6);
-		properties.add(propertyDefinition7);
-		properties.add(propertyDefinition8);
-		properties.add(propertyDefinition9);
+        properties.add(propertyDefinition1);
+        properties.add(propertyDefinition2);
+        properties.add(propertyDefinition3);
+        properties.add(propertyDefinition4);
+        properties.add(propertyDefinition5);
+        properties.add(propertyDefinition6);
+        properties.add(propertyDefinition7);
+        properties.add(propertyDefinition8);
+        properties.add(propertyDefinition9);
 
-		dataTypeDefinition.setProperties(properties);
-		return dataTypeDefinition;
-	}
+        dataTypeDefinition.setProperties(properties);
+        return dataTypeDefinition;
+    }
 
-	private static DataTypeDefinition buildCityDataType() {
-		DataTypeDefinition cityDataType = new DataTypeDefinition();
-		cityDataType.setName("city");
-		List<PropertyDefinition> cityProperties = new ArrayList<>();
-		PropertyDefinition cityPropertyDefinition1 = new PropertyDefinition();
-		cityPropertyDefinition1.setName("age");
-		cityPropertyDefinition1.setType(ToscaPropertyType.INTEGER.getType());
-		PropertyDefinition cityPropertyDefinition2 = new PropertyDefinition();
-		cityPropertyDefinition2.setName("address");
-		cityPropertyDefinition2.setType(ToscaPropertyType.STRING.getType());
+    private static DataTypeDefinition buildCityDataType() {
+        DataTypeDefinition cityDataType = new DataTypeDefinition();
+        cityDataType.setName("city");
+        List<PropertyDefinition> cityProperties = new ArrayList<>();
+        PropertyDefinition cityPropertyDefinition1 = new PropertyDefinition();
+        cityPropertyDefinition1.setName("age");
+        cityPropertyDefinition1.setType(ToscaPropertyType.INTEGER.getType());
+        PropertyDefinition cityPropertyDefinition2 = new PropertyDefinition();
+        cityPropertyDefinition2.setName("address");
+        cityPropertyDefinition2.setType(ToscaPropertyType.STRING.getType());
 
-		cityProperties.add(cityPropertyDefinition1);
-		cityProperties.add(cityPropertyDefinition2);
+        cityProperties.add(cityPropertyDefinition1);
+        cityProperties.add(cityPropertyDefinition2);
 
-		cityDataType.setProperties(cityProperties);
-		return cityDataType;
-	}
+        cityDataType.setProperties(cityProperties);
+        return cityDataType;
+    }
 
-	private static DataTypeDefinition buildPersonDataType() {
-		DataTypeDefinition personDataType = new DataTypeDefinition();
-		personDataType.setName("person");
-		List<PropertyDefinition> personProperties = new ArrayList<>();
-		PropertyDefinition personPropertyDefinition1 = new PropertyDefinition();
-		personPropertyDefinition1.setName("age");
-		personPropertyDefinition1.setType("myinteger");
-		PropertyDefinition personPropertyDefinition2 = new PropertyDefinition();
-		personPropertyDefinition2.setName("address");
-		personPropertyDefinition2.setType(ToscaPropertyType.STRING.getType());
+    private static DataTypeDefinition buildPersonDataType() {
+        DataTypeDefinition personDataType = new DataTypeDefinition();
+        personDataType.setName("person");
+        List<PropertyDefinition> personProperties = new ArrayList<>();
+        PropertyDefinition personPropertyDefinition1 = new PropertyDefinition();
+        personPropertyDefinition1.setName("age");
+        personPropertyDefinition1.setType("myinteger");
+        PropertyDefinition personPropertyDefinition2 = new PropertyDefinition();
+        personPropertyDefinition2.setName("address");
+        personPropertyDefinition2.setType(ToscaPropertyType.STRING.getType());
 
-		personProperties.add(personPropertyDefinition1);
-		personProperties.add(personPropertyDefinition2);
+        personProperties.add(personPropertyDefinition1);
+        personProperties.add(personPropertyDefinition2);
 
-		personDataType.setProperties(personProperties);
-		return personDataType;
-	}
+        personDataType.setProperties(personProperties);
+        return personDataType;
+    }
 
-	private static DataTypeDefinition buildFileDataType() {
-		DataTypeDefinition fileDataType = new DataTypeDefinition();
-		fileDataType.setName("file");
-		List<PropertyDefinition> fileProperties = new ArrayList<>();
-		PropertyDefinition filePropertyDefinition1 = new PropertyDefinition();
-		filePropertyDefinition1.setName("age");
-		filePropertyDefinition1.setType("integer");
+    private static DataTypeDefinition buildFileDataType() {
+        DataTypeDefinition fileDataType = new DataTypeDefinition();
+        fileDataType.setName("file");
+        List<PropertyDefinition> fileProperties = new ArrayList<>();
+        PropertyDefinition filePropertyDefinition1 = new PropertyDefinition();
+        filePropertyDefinition1.setName("age");
+        filePropertyDefinition1.setType("integer");
 
-		PropertyDefinition filePropertyDefinition2 = new PropertyDefinition();
-		filePropertyDefinition2.setName("attributes");
-		filePropertyDefinition2.setType(ToscaPropertyType.MAP.getType());
+        PropertyDefinition filePropertyDefinition2 = new PropertyDefinition();
+        filePropertyDefinition2.setName("attributes");
+        filePropertyDefinition2.setType(ToscaPropertyType.MAP.getType());
 
-		fileProperties.add(filePropertyDefinition1);
-		fileProperties.add(filePropertyDefinition2);
+        fileProperties.add(filePropertyDefinition1);
+        fileProperties.add(filePropertyDefinition2);
 
-		SchemaDefinition entrySchema = new SchemaDefinition();
-		PropertyDataDefinition property = new PropertyDataDefinition();
-		property.setType("city");
-		entrySchema.setProperty(property);
-		filePropertyDefinition2.setSchema(entrySchema);
+        SchemaDefinition entrySchema = new SchemaDefinition();
+        PropertyDataDefinition property = new PropertyDataDefinition();
+        property.setType("city");
+        entrySchema.setProperty(property);
+        filePropertyDefinition2.setSchema(entrySchema);
 
-		fileDataType.setProperties(fileProperties);
-		return fileDataType;
-	}
+        fileDataType.setProperties(fileProperties);
+        return fileDataType;
+    }
 
-	private static DataTypeDefinition getPrimitiveDataType(String type) {
+    private static DataTypeDefinition getPrimitiveDataType(String type) {
 
-		DataTypeDefinition derivedFrom = new DataTypeDefinition();
-		derivedFrom.setName(type);
+        DataTypeDefinition derivedFrom = new DataTypeDefinition();
+        derivedFrom.setName(type);
 
-		return derivedFrom;
+        return derivedFrom;
 
-	}
+    }
 
-	private static DataTypeDefinition buildDerivedFromIntegerType() {
+    private static DataTypeDefinition buildDerivedFromIntegerType() {
 
-		DataTypeDefinition derivedFrom = getPrimitiveDataType("integer");
+        DataTypeDefinition derivedFrom = getPrimitiveDataType("integer");
 
-		DataTypeDefinition myIntegerDataType = new DataTypeDefinition();
-		myIntegerDataType.setDerivedFrom(derivedFrom);
+        DataTypeDefinition myIntegerDataType = new DataTypeDefinition();
+        myIntegerDataType.setDerivedFrom(derivedFrom);
 
-		myIntegerDataType.setName("myinteger");
+        myIntegerDataType.setName("myinteger");
 
-		return myIntegerDataType;
-	}
+        return myIntegerDataType;
+    }
 
-	public static class MyFile {
+    public static class MyFile {
 
-		Integer age;
+        Integer age;
 
-		Map<String, City> attributes;
+        Map<String, City> attributes;
 
-		public Integer getAge() {
-			return age;
-		}
+        public Integer getAge() {
+            return age;
+        }
 
-		public void setAge(Integer age) {
-			this.age = age;
-		}
+        public void setAge(Integer age) {
+            this.age = age;
+        }
 
-		public Map<String, City> getAttributes() {
-			return attributes;
-		}
+        public Map<String, City> getAttributes() {
+            return attributes;
+        }
 
-		public void setAttributes(Map<String, City> attributes) {
-			this.attributes = attributes;
-		}
+        public void setAttributes(Map<String, City> attributes) {
+            this.attributes = attributes;
+        }
 
-	}
+    }
 
-	public static class City {
+    public static class City {
 
-		String address;
-		Integer age;
+        String address;
+        Integer age;
 
-		public City(String address, Integer age) {
-			super();
-			this.address = address;
-			this.age = age;
-		}
+        public City(String address, Integer age) {
+            super();
+            this.address = address;
+            this.age = age;
+        }
 
-		public String getAddress() {
-			return address;
-		}
+        public String getAddress() {
+            return address;
+        }
 
-		public void setAddress(String address) {
-			this.address = address;
-		}
+        public void setAddress(String address) {
+            this.address = address;
+        }
 
-		public Integer getAge() {
-			return age;
-		}
+        public Integer getAge() {
+            return age;
+        }
 
-		public void setAge(Integer age) {
-			this.age = age;
-		}
+        public void setAge(Integer age) {
+            this.age = age;
+        }
 
-	}
+    }
 
-	public static class Person {
+    public static class Person {
 
-		String address;
-		Integer age;
+        String address;
+        Integer age;
 
-		public Person(String address, Integer age) {
-			super();
-			this.address = address;
-			this.age = age;
-		}
+        public Person(String address, Integer age) {
+            super();
+            this.address = address;
+            this.age = age;
+        }
 
-		public String getAddress() {
-			return address;
-		}
+        public String getAddress() {
+            return address;
+        }
 
-		public void setAddress(String address) {
-			this.address = address;
-		}
+        public void setAddress(String address) {
+            this.address = address;
+        }
 
-		public Integer getAge() {
-			return age;
-		}
+        public Integer getAge() {
+            return age;
+        }
 
-		public void setAge(Integer age) {
-			this.age = age;
-		}
+        public void setAge(Integer age) {
+            this.age = age;
+        }
 
-		@Override
-		public String toString() {
-			return "Person [address=" + address + ", age=" + age + "]";
-		}
+        @Override
+        public String toString() {
+            return "Person [address=" + address + ", age=" + age + "]";
+        }
 
-	}
+    }
 
-	public static class Credential {
+    public static class Credential {
 
-		String protocol;
-		Integer sum;
-		String token_type;
-		String token;
-		Map<String, String> keys;
-		String user;
-		Boolean isMandatory;
-		List<String> mylist;
-		City mycity;
+        String protocol;
+        Integer sum;
+        String token_type;
+        String token;
+        Map<String, String> keys;
+        String user;
+        Boolean isMandatory;
+        List<String> mylist;
+        City mycity;
 
-		public Credential(String protocol, Integer sum, String token_type, String token, Map<String, String> keys,
-				String user, Boolean isMandatory, List<String> mylist) {
-			super();
-			this.protocol = protocol;
-			this.sum = sum;
-			this.token_type = token_type;
-			this.token = token;
-			this.keys = keys;
-			this.user = user;
-			this.isMandatory = isMandatory;
-			this.mylist = mylist;
-		}
+        public Credential(String protocol, Integer sum, String token_type, String token, Map<String, String> keys,
+                String user, Boolean isMandatory, List<String> mylist) {
+            super();
+            this.protocol = protocol;
+            this.sum = sum;
+            this.token_type = token_type;
+            this.token = token;
+            this.keys = keys;
+            this.user = user;
+            this.isMandatory = isMandatory;
+            this.mylist = mylist;
+        }
 
-		public String getProtocol() {
-			return protocol;
-		}
+        public String getProtocol() {
+            return protocol;
+        }
 
-		public void setProtocol(String protocol) {
-			this.protocol = protocol;
-		}
+        public void setProtocol(String protocol) {
+            this.protocol = protocol;
+        }
 
-		public String getToken_type() {
-			return token_type;
-		}
+        public String getToken_type() {
+            return token_type;
+        }
 
-		public void setToken_type(String token_type) {
-			this.token_type = token_type;
-		}
+        public void setToken_type(String token_type) {
+            this.token_type = token_type;
+        }
 
-		public String getToken() {
-			return token;
-		}
+        public String getToken() {
+            return token;
+        }
 
-		public void setToken(String token) {
-			this.token = token;
-		}
+        public void setToken(String token) {
+            this.token = token;
+        }
 
-		public Map<String, String> getKeys() {
-			return keys;
-		}
+        public Map<String, String> getKeys() {
+            return keys;
+        }
 
-		public void setKeys(Map<String, String> keys) {
-			this.keys = keys;
-		}
+        public void setKeys(Map<String, String> keys) {
+            this.keys = keys;
+        }
 
-		public String getUser() {
-			return user;
-		}
+        public String getUser() {
+            return user;
+        }
 
-		public void setUser(String user) {
-			this.user = user;
-		}
+        public void setUser(String user) {
+            this.user = user;
+        }
 
-		public Boolean getIsMandatory() {
-			return isMandatory;
-		}
+        public Boolean getIsMandatory() {
+            return isMandatory;
+        }
 
-		public void setIsMandatory(Boolean isMandatory) {
-			this.isMandatory = isMandatory;
-		}
+        public void setIsMandatory(Boolean isMandatory) {
+            this.isMandatory = isMandatory;
+        }
 
-		public Integer getSum() {
-			return sum;
-		}
+        public Integer getSum() {
+            return sum;
+        }
 
-		public void setSum(Integer sum) {
-			this.sum = sum;
-		}
+        public void setSum(Integer sum) {
+            this.sum = sum;
+        }
 
-		public List<String> getMylist() {
-			return mylist;
-		}
+        public List<String> getMylist() {
+            return mylist;
+        }
 
-		public void setMylist(List<String> mylist) {
-			this.mylist = mylist;
-		}
+        public void setMylist(List<String> mylist) {
+            this.mylist = mylist;
+        }
 
-		public City getMycity() {
-			return mycity;
-		}
+        public City getMycity() {
+            return mycity;
+        }
 
-		public void setMycity(City mycity) {
-			this.mycity = mycity;
-		}
+        public void setMycity(City mycity) {
+            this.mycity = mycity;
+        }
 
-		@Override
-		public String toString() {
-			return "Credential [protocol=" + protocol + ", token_type=" + token_type + ", token=" + token + ", keys="
-					+ keys + ", user=" + user + ", isMandatory=" + isMandatory + "]";
-		}
+        @Override
+        public String toString() {
+            return "Credential [protocol=" + protocol + ", token_type=" + token_type + ", token=" + token + ", keys="
+                    + keys + ", user=" + user + ", isMandatory=" + isMandatory + "]";
+        }
 
-	}
+    }
 
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/OperationTestsUtil.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/OperationTestsUtil.java
index e356b49..a0b6ea6 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/OperationTestsUtil.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/OperationTestsUtil.java
@@ -20,6 +20,7 @@
 
 package org.openecomp.sdc.be.model.operations.impl.util;
 
+import fj.data.Either;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
@@ -33,63 +34,61 @@
 import org.openecomp.sdc.be.resources.data.category.SubCategoryData;
 import org.openecomp.sdc.common.util.ValidationUtils;
 
-import fj.data.Either;
-
 public class OperationTestsUtil {
 
-	public static String deleteAndCreateServiceCategory(String category, TitanGenericDao titanDao) {
-		CategoryData categoryData = new CategoryData(NodeTypeEnum.ServiceNewCategory);
-		categoryData.getCategoryDataDefinition().setName(category);
-		categoryData.getCategoryDataDefinition()
-				.setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(category));
-		categoryData.getCategoryDataDefinition().setUniqueId(UniqueIdBuilder.buildCategoryUid(
-				ValidationUtils.normalizeCategoryName4Uniqueness(category), NodeTypeEnum.ServiceNewCategory));
-		titanDao.deleteNode(categoryData, CategoryData.class);
-		Either<CategoryData, TitanOperationStatus> createNode = titanDao.createNode(categoryData, CategoryData.class);
-		return (String) createNode.left().value().getUniqueId();
-	}
+    public static String deleteAndCreateServiceCategory(String category, TitanGenericDao titanDao) {
+        CategoryData categoryData = new CategoryData(NodeTypeEnum.ServiceNewCategory);
+        categoryData.getCategoryDataDefinition().setName(category);
+        categoryData.getCategoryDataDefinition()
+                .setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(category));
+        categoryData.getCategoryDataDefinition().setUniqueId(UniqueIdBuilder.buildCategoryUid(
+                ValidationUtils.normalizeCategoryName4Uniqueness(category), NodeTypeEnum.ServiceNewCategory));
+        titanDao.deleteNode(categoryData, CategoryData.class);
+        Either<CategoryData, TitanOperationStatus> createNode = titanDao.createNode(categoryData, CategoryData.class);
+        return (String) createNode.left().value().getUniqueId();
+    }
 
-	public static String deleteAndCreateResourceCategory(String category, String subcategory,
-			TitanGenericDao titanDao) {
+    public static String deleteAndCreateResourceCategory(String category, String subcategory,
+            TitanGenericDao titanDao) {
 
-		CategoryData categoryData = new CategoryData(NodeTypeEnum.ResourceNewCategory);
-		categoryData.getCategoryDataDefinition().setName(category);
-		categoryData.getCategoryDataDefinition()
-				.setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(category));
-		categoryData.getCategoryDataDefinition().setUniqueId(UniqueIdBuilder.buildCategoryUid(
-				ValidationUtils.normalizeCategoryName4Uniqueness(category), NodeTypeEnum.ResourceNewCategory));
+        CategoryData categoryData = new CategoryData(NodeTypeEnum.ResourceNewCategory);
+        categoryData.getCategoryDataDefinition().setName(category);
+        categoryData.getCategoryDataDefinition()
+                .setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(category));
+        categoryData.getCategoryDataDefinition().setUniqueId(UniqueIdBuilder.buildCategoryUid(
+                ValidationUtils.normalizeCategoryName4Uniqueness(category), NodeTypeEnum.ResourceNewCategory));
 
-		SubCategoryData subcategoryData = new SubCategoryData(NodeTypeEnum.ResourceSubcategory);
-		subcategoryData.getSubCategoryDataDefinition().setName(subcategory);
-		subcategoryData.getSubCategoryDataDefinition()
-				.setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(subcategory));
-		subcategoryData.getSubCategoryDataDefinition().setUniqueId(UniqueIdBuilder
-				.buildSubCategoryUid(categoryData.getCategoryDataDefinition().getUniqueId(), subcategory));
-		titanDao.deleteNode(categoryData, CategoryData.class);
-		titanDao.deleteNode(subcategoryData, SubCategoryData.class);
-		Either<CategoryData, TitanOperationStatus> createNode = titanDao.createNode(categoryData, CategoryData.class);
-		titanDao.createNode(subcategoryData, SubCategoryData.class);
-		titanDao.createRelation(categoryData, subcategoryData, GraphEdgeLabels.SUB_CATEGORY, null);
-		return (String) createNode.left().value().getUniqueId();
-	}
+        SubCategoryData subcategoryData = new SubCategoryData(NodeTypeEnum.ResourceSubcategory);
+        subcategoryData.getSubCategoryDataDefinition().setName(subcategory);
+        subcategoryData.getSubCategoryDataDefinition()
+                .setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(subcategory));
+        subcategoryData.getSubCategoryDataDefinition().setUniqueId(UniqueIdBuilder
+                .buildSubCategoryUid(categoryData.getCategoryDataDefinition().getUniqueId(), subcategory));
+        titanDao.deleteNode(categoryData, CategoryData.class);
+        titanDao.deleteNode(subcategoryData, SubCategoryData.class);
+        Either<CategoryData, TitanOperationStatus> createNode = titanDao.createNode(categoryData, CategoryData.class);
+        titanDao.createNode(subcategoryData, SubCategoryData.class);
+        titanDao.createRelation(categoryData, subcategoryData, GraphEdgeLabels.SUB_CATEGORY, null);
+        return (String) createNode.left().value().getUniqueId();
+    }
 
-	public static void deleteServiceCategory(String category, TitanGenericDao titanDao) {
-		ServiceCategoryData categoryData = new ServiceCategoryData(category);
-		titanDao.deleteNode(categoryData, ServiceCategoryData.class);
-	}
+    public static void deleteServiceCategory(String category, TitanGenericDao titanDao) {
+        ServiceCategoryData categoryData = new ServiceCategoryData(category);
+        titanDao.deleteNode(categoryData, ServiceCategoryData.class);
+    }
 
-	public static void deleteResourceCategory(String category, String subcategory, TitanGenericDao titanDao) {
-		ResourceCategoryData categoryData = new ResourceCategoryData(category, subcategory);
-		titanDao.deleteNode(categoryData, ResourceCategoryData.class);
-	}
+    public static void deleteResourceCategory(String category, String subcategory, TitanGenericDao titanDao) {
+        ResourceCategoryData categoryData = new ResourceCategoryData(category, subcategory);
+        titanDao.deleteNode(categoryData, ResourceCategoryData.class);
+    }
 
-	public static User convertUserDataToUser(UserData modifierData) {
-		User modifier = new User();
-		modifier.setUserId(modifierData.getUserId());
-		modifier.setEmail(modifierData.getEmail());
-		modifier.setFirstName(modifierData.getFirstName());
-		modifier.setLastName(modifierData.getLastName());
-		modifier.setRole(modifierData.getRole());
-		return modifier;
-	}
+    public static User convertUserDataToUser(UserData modifierData) {
+        User modifier = new User();
+        modifier.setUserId(modifierData.getUserId());
+        modifier.setEmail(modifierData.getEmail());
+        modifier.setFirstName(modifierData.getFirstName());
+        modifier.setLastName(modifierData.getLastName());
+        modifier.setRole(modifierData.getRole());
+        return modifier;
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/PrintGraph.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/PrintGraph.java
index c305b12..7ba2e09 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/PrintGraph.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/PrintGraph.java
@@ -32,340 +32,339 @@
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.util.*;
+import java.util.Map.Entry;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
 public class PrintGraph {
 
-	public void printGraphVertices(TitanGraph graph) {
+    public void printGraphVertices(TitanGraph graph) {
 
-		Iterable<TitanVertex> vertices = graph.query().vertices();
+        Iterable<TitanVertex> vertices = graph.query().vertices();
 
-		if (vertices != null) {
-			Iterator<TitanVertex> iterator = vertices.iterator();
-			while (iterator.hasNext()) {
-				Vertex vertex = iterator.next();
-			}
+        if (vertices != null) {
+            Iterator<TitanVertex> iterator = vertices.iterator();
+            while (iterator.hasNext()) {
+                Vertex vertex = iterator.next();
+            }
 
-		}
-		// graph.commit();
-		graph.tx().commit();
-	}
+        }
+        // graph.commit();
+        graph.tx().commit();
+    }
 
-	public void printGraphEdges(TitanGraph graph) {
-		Iterable<TitanEdge> vertices = graph.query().edges();
+    public void printGraphEdges(TitanGraph graph) {
+        Iterable<TitanEdge> vertices = graph.query().edges();
 
-		if (vertices != null) {
-			Iterator<TitanEdge> iterator = vertices.iterator();
-			while (iterator.hasNext()) {
-				Edge edge = iterator.next();
+        if (vertices != null) {
+            Iterator<TitanEdge> iterator = vertices.iterator();
+            while (iterator.hasNext()) {
+                Edge edge = iterator.next();
 
-			}
+            }
 
-		}
-		graph.tx().commit();
-	}
+        }
+        graph.tx().commit();
+    }
 
-	public String buildGraphForWebgraphWiz(TitanGraph graph) {
+    public String buildGraphForWebgraphWiz(TitanGraph graph) {
 
-		StringBuilder builder = new StringBuilder();
-		builder.append("digraph finite_state_machine {\n");
-		builder.append("rankdir=LR;\n");
-		builder.append("size=\"15,10\" \n");
-		Iterable<TitanVertex> vertices = graph.query().vertices();
+        StringBuilder builder = new StringBuilder();
+        builder.append("digraph finite_state_machine {\n");
+        builder.append("rankdir=LR;\n");
+        builder.append("size=\"15,10\" \n");
+        Iterable<TitanVertex> vertices = graph.query().vertices();
 
-		if (vertices != null) {
-			Iterator<TitanVertex> iterator = vertices.iterator();
-			while (iterator.hasNext()) {
-				Vertex vertex = iterator.next();
+        if (vertices != null) {
+            Iterator<TitanVertex> iterator = vertices.iterator();
+            while (iterator.hasNext()) {
+                Vertex vertex = iterator.next();
 
-				Map<String, Object> properties = getProperties(vertex);
+                Map<String, Object> properties = getProperties(vertex);
 
-				String nodeLabel = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty());
+                String nodeLabel = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty());
 
-				String color = getColorByNodeType(nodeLabel);
+                String color = getColorByNodeType(nodeLabel);
 
-				String uid = getNodeIdByLabel(nodeLabel, properties);
+                String uid = getNodeIdByLabel(nodeLabel, properties);
 
-				String nodeRecord = buildNodeRecord(uid, color, properties);
+                String nodeRecord = buildNodeRecord(uid, color, properties);
 
-				builder.append(nodeRecord);
+                builder.append(nodeRecord);
 
-			}
+            }
 
-		}
+        }
 
-		Iterable<TitanEdge> edges = graph.query().edges();
+        Iterable<TitanEdge> edges = graph.query().edges();
 
-		if (edges != null) {
-			Iterator<TitanEdge> iterator = edges.iterator();
-			while (iterator.hasNext()) {
-				Edge edge = iterator.next();
+        if (edges != null) {
+            Iterator<TitanEdge> iterator = edges.iterator();
+            while (iterator.hasNext()) {
+                Edge edge = iterator.next();
 
-				Vertex vertexFrom = edge.outVertex();
-				Vertex vertexTo = edge.inVertex();
-				String fromUid = getNodeIdByLabel(vertexFrom.value(GraphPropertiesDictionary.LABEL.getProperty()),
-						getProperties(vertexFrom));
-				String toUid = getNodeIdByLabel(vertexTo.value(GraphPropertiesDictionary.LABEL.getProperty()),
-						getProperties(vertexTo));
+                Vertex vertexFrom = edge.outVertex();
+                Vertex vertexTo = edge.inVertex();
+                String fromUid = getNodeIdByLabel(vertexFrom.value(GraphPropertiesDictionary.LABEL.getProperty()),
+                        getProperties(vertexFrom));
+                String toUid = getNodeIdByLabel(vertexTo.value(GraphPropertiesDictionary.LABEL.getProperty()),
+                        getProperties(vertexTo));
 
-				String edgeLabel = edge.label();
+                String edgeLabel = edge.label();
 
-				String edgeRecord = buildEdgeRecord(fromUid, toUid, edgeLabel, getProperties(edge));
+                String edgeRecord = buildEdgeRecord(fromUid, toUid, edgeLabel, getProperties(edge));
 
-				builder.append(edgeRecord);
-			}
+                builder.append(edgeRecord);
+            }
 
-		}
+        }
 
-		builder.append(" } ");
+        builder.append(" } ");
 
-		return builder.toString();
+        return builder.toString();
 
-	}
+    }
 
 
-	private String buildEdgeRecord(String fromUid, String toUid, String edgeLabel, Map<String, Object> properties) {
+    private String buildEdgeRecord(String fromUid, String toUid, String edgeLabel, Map<String, Object> properties) {
 
-		StringBuilder builder = new StringBuilder();
-		// LR_0 -> LR_2 [ label = "SS(B)" ];
+        StringBuilder builder = new StringBuilder();
+        // LR_0 -> LR_2 [ label = "SS(B)" ];
 
-		String generatedProps = generateStringFromProperties(properties);
+        String generatedProps = generateStringFromProperties(properties);
 
-		String color = getEdgeColorByLabel(edgeLabel);
+        String color = getEdgeColorByLabel(edgeLabel);
 
-		builder.append("\"" + fromUid + "\"" + " -> " + "\"" + toUid + "\"" + " [ color = " + color + " label = \""
-				+ edgeLabel + "(" + generatedProps + ")\"" + " ] " + "\n");
+        builder.append("\"" + fromUid + "\"" + " -> " + "\"" + toUid + "\"" + " [ color = " + color + " label = \""
+                + edgeLabel + "(" + generatedProps + ")\"" + " ] " + "\n");
 
-		return builder.toString();
-	}
+        return builder.toString();
+    }
 
-	private String getEdgeColorByLabel(String edgeLabel) {
+    private String getEdgeColorByLabel(String edgeLabel) {
 
-		GraphEdgeLabels edgeLabelEnum = GraphEdgeLabels.getByName(edgeLabel);
+        GraphEdgeLabels edgeLabelEnum = GraphEdgeLabels.getByName(edgeLabel);
 
-		String color = "black";
+        String color = "black";
 
-		switch (edgeLabelEnum) {
-		case PROPERTY:
-			color = "orange";
-			break;
-		case CAPABILITY:
-			break;
-		case DERIVED_FROM:
-			color = "red";
-		default:
-			break;
-		}
+        switch (edgeLabelEnum) {
+        case PROPERTY:
+            color = "orange";
+            break;
+        case CAPABILITY:
+            break;
+        case DERIVED_FROM:
+            color = "red";
+        default:
+            break;
+        }
 
-		return color;
-	}
+        return color;
+    }
 
-	private String generateStringFromProperties(Map<String, Object> properties) {
+    private String generateStringFromProperties(Map<String, Object> properties) {
 
-		StringBuilder builder = new StringBuilder();
+        StringBuilder builder = new StringBuilder();
 
-		if (properties != null) {
-			for (Entry<String, Object> entry : properties.entrySet()) {
-				String key = entry.getKey();
-				String value = entry.getValue().toString();
-				builder.append(key + "=" + value + "__");
-			}
-		}
-		return builder.toString();
+        if (properties != null) {
+            for (Entry<String, Object> entry : properties.entrySet()) {
+                String key = entry.getKey();
+                String value = entry.getValue().toString();
+                builder.append(key + "=" + value + "__");
+            }
+        }
+        return builder.toString();
 
-	}
+    }
 
-	private String buildNodeRecord(String uid, String color, Map<String, Object> properties) {
+    private String buildNodeRecord(String uid, String color, Map<String, Object> properties) {
 
-		StringBuilder builder = new StringBuilder();
+        StringBuilder builder = new StringBuilder();
 
-		builder.append("\"" + uid + "\"" + " [ ");
-		builder.append("style = \"bold\" ");
-		builder.append(" color = \"" + color + "\"");
-		builder.append("shape = \"Mrecord\" ");
+        builder.append("\"" + uid + "\"" + " [ ");
+        builder.append("style = \"bold\" ");
+        builder.append(" color = \"" + color + "\"");
+        builder.append("shape = \"Mrecord\" ");
 
-		String label = "";
-		int maxKeyLength = 0;
-		for (Entry<String, Object> entry1 : properties.entrySet()) {
-			String key = entry1.getKey();
-			int keyLength = key.length();
-			if (keyLength > maxKeyLength) {
-				maxKeyLength = keyLength;
-			}
-		}
+        String label = "";
+        int maxKeyLength = 0;
+        for (Entry<String, Object> entry1 : properties.entrySet()) {
+            String key = entry1.getKey();
+            int keyLength = key.length();
+            if (keyLength > maxKeyLength) {
+                maxKeyLength = keyLength;
+            }
+        }
 
-		boolean first = true;
-		for (Entry<String, Object> entry : properties.entrySet()) {
+        boolean first = true;
+        for (Entry<String, Object> entry : properties.entrySet()) {
 
-			String key = entry.getKey();
-			String value = entry.getValue().toString();
+            String key = entry.getKey();
+            String value = entry.getValue().toString();
 
-			if (key.equals(GraphPropertiesDictionary.CONSTRAINTS.getProperty())) {
-				value = value.replaceAll("[^\\w\\s]", "_");
-			}
+            if (key.equals(GraphPropertiesDictionary.CONSTRAINTS.getProperty())) {
+                value = value.replaceAll("[^\\w\\s]", "_");
+            }
 
-			key = padKey(key, maxKeyLength);
+            key = padKey(key, maxKeyLength);
 
-			if (first) {
-				first = false;
-			} else {
-				label += " | ";
-			}
-			label += " { " + key + " | " + value + " } ";
-		}
+            if (first) {
+                first = false;
+            } else {
+                label += " | ";
+            }
+            label += " { " + key + " | " + value + " } ";
+        }
 
-		builder.append("label = \"" + label + "\" ");
-		builder.append(" ] ");
-		builder.append(" \n ");
-		return builder.toString();
-	}
+        builder.append("label = \"" + label + "\" ");
+        builder.append(" ] ");
+        builder.append(" \n ");
+        return builder.toString();
+    }
 
-	private String getNodeIdByLabel(String nodeLabel, Map<String, Object> properties) {
+    private String getNodeIdByLabel(String nodeLabel, Map<String, Object> properties) {
 
-		NodeTypeEnum typeEnum = NodeTypeEnum.getByName(nodeLabel);
+        NodeTypeEnum typeEnum = NodeTypeEnum.getByName(nodeLabel);
 
-		String uid = null;
-		switch (typeEnum) {
+        String uid = null;
+        switch (typeEnum) {
 
-		case User:
-			uid = (String) properties.get(GraphPropertiesDictionary.USERID.getProperty());
-			break;
-		case ServiceCategory:
-		case ResourceCategory:
-		case Tag:
-			uid = (String) properties.get(GraphPropertiesDictionary.NAME.getProperty());
-			break;
+        case User:
+            uid = (String) properties.get(GraphPropertiesDictionary.USERID.getProperty());
+            break;
+        case ServiceCategory:
+        case ResourceCategory:
+        case Tag:
+            uid = (String) properties.get(GraphPropertiesDictionary.NAME.getProperty());
+            break;
 
-		default:
-			uid = (String) properties.get(GraphPropertiesDictionary.UNIQUE_ID.getProperty());
-			break;
-		}
+        default:
+            uid = (String) properties.get(GraphPropertiesDictionary.UNIQUE_ID.getProperty());
+            break;
+        }
 
-		return uid;
-	}
+        return uid;
+    }
 
-	private String getColorByNodeType(String nodeLabel) {
+    private String getColorByNodeType(String nodeLabel) {
 
-		NodeTypeEnum typeEnum = NodeTypeEnum.getByName(nodeLabel);
+        NodeTypeEnum typeEnum = NodeTypeEnum.getByName(nodeLabel);
 
-		String color = "red";
-		switch (typeEnum) {
-		case ServiceCategory:
-			color = "blue";
-			break;
-		case ResourceCategory:
-			color = "blue";
-			break;
-		case Resource:
-			color = "forestgreen";
-			break;
-		case User:
-			color = "green";
-			break;
-		case Capability:
-			color = "lightgreen";
-			break;
-		case CapabilityType:
-			color = "gray";
-			break;
-		case Property:
-			color = "cyan";
-			break;
-		case RelationshipType:
-			color = "darkorchid";
-			break;
-		case Requirement:
-			color = "gold";
-			break;
-		case RequirementImpl:
-			// color = "forestgreen";
-			color = "gold";
-			break;
-		case Service:
-			color = "cyan4";
-			break;
-		case Tag:
-			color = "dimgrey";
-			break;
-		default:
-			break;
+        String color = "red";
+        switch (typeEnum) {
+        case ServiceCategory:
+            color = "blue";
+            break;
+        case ResourceCategory:
+            color = "blue";
+            break;
+        case Resource:
+            color = "forestgreen";
+            break;
+        case User:
+            color = "green";
+            break;
+        case Capability:
+            color = "lightgreen";
+            break;
+        case CapabilityType:
+            color = "gray";
+            break;
+        case Property:
+            color = "cyan";
+            break;
+        case RelationshipType:
+            color = "darkorchid";
+            break;
+        case Requirement:
+            color = "gold";
+            break;
+        case RequirementImpl:
+            // color = "forestgreen";
+            color = "gold";
+            break;
+        case Service:
+            color = "cyan4";
+            break;
+        case Tag:
+            color = "dimgrey";
+            break;
+        default:
+            break;
 
-		}
+        }
 
-		return color;
-	}
+        return color;
+    }
 
-	private String padKey(String key, int maxKeyLength) {
+    private String padKey(String key, int maxKeyLength) {
 
-		int len = key.length();
-		for (int i = len; i < maxKeyLength; i++) {
-			key += " ";
-		}
+        int len = key.length();
+        for (int i = len; i < maxKeyLength; i++) {
+            key += " ";
+        }
 
-		return key;
-	}
+        return key;
+    }
 
-	public int getNumberOfVertices(TitanGraph graph) {
-		int counter = 0;
-		Iterable<TitanVertex> vertices = graph.query().vertices();
+    public int getNumberOfVertices(TitanGraph graph) {
+        int counter = 0;
+        Iterable<TitanVertex> vertices = graph.query().vertices();
 
-		if (vertices != null) {
-			Iterator<TitanVertex> iterator = vertices.iterator();
-			while (iterator.hasNext()) {
-				Vertex vertex = iterator.next();
-				counter++;
-			}
-		}
-		return counter;
-	}
+        if (vertices != null) {
+            Iterator<TitanVertex> iterator = vertices.iterator();
+            while (iterator.hasNext()) {
+                Vertex vertex = iterator.next();
+                counter++;
+            }
+        }
+        return counter;
+    }
 
-	public Set<String> getVerticesSet(TitanGraph titanGraph) {
+    public Set<String> getVerticesSet(TitanGraph titanGraph) {
 
-		Set<String> set = new HashSet<String>();
+        Set<String> set = new HashSet<>();
 
-		Iterable<TitanVertex> vertices = titanGraph.query().vertices();
+        Iterable<TitanVertex> vertices = titanGraph.query().vertices();
 
-		if (vertices != null) {
-			Iterator<TitanVertex> iterator = vertices.iterator();
-			while (iterator.hasNext()) {
-				Vertex vertex = iterator.next();
+        if (vertices != null) {
+            Iterator<TitanVertex> iterator = vertices.iterator();
+            while (iterator.hasNext()) {
+                Vertex vertex = iterator.next();
 
-				Map<String, Object> properties = getProperties(vertex);
+                Map<String, Object> properties = getProperties(vertex);
 
-				String nodeLabel = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty());
+                String nodeLabel = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty());
 
-				String uid = getNodeIdByLabel(nodeLabel, properties);
+                String uid = getNodeIdByLabel(nodeLabel, properties);
 
-				set.add(uid);
-			}
-		}
+                set.add(uid);
+            }
+        }
 
-		return set;
+        return set;
 
-	}
+    }
 
-	public Map<String, Object> getProperties(Element element) {
+    public Map<String, Object> getProperties(Element element) {
 
-		Map<String, Object> result = null;
+        Map<String, Object> result = null;
 
-		if (element.keys() != null && element.keys().size() > 0) {
-			Map<String, Property> propertyMap = ElementHelper.propertyMap(element,
-					element.keys().toArray(new String[element.keys().size()]));
-			result = new HashMap<String, Object>();
+        if (element.keys() != null && element.keys().size() > 0) {
+            Map<String, Property> propertyMap = ElementHelper.propertyMap(element,
+                    element.keys().toArray(new String[element.keys().size()]));
+            result = new HashMap<>();
 
-			for (Entry<String, Property> entry : propertyMap.entrySet()) {
-				String key = entry.getKey();
-				Object value = entry.getValue().value();
+            for (Entry<String, Property> entry : propertyMap.entrySet()) {
+                String key = entry.getKey();
+                Object value = entry.getValue().value();
 
-				result.put(key, value);
-			}
-		}
-		return result;
-	}
+                result.put(key, value);
+            }
+        }
+        return result;
+    }
 
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/ResourceCreationUtils.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/ResourceCreationUtils.java
index b6b951b..ae32bb1 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/ResourceCreationUtils.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/ResourceCreationUtils.java
@@ -22,15 +22,15 @@
 
 public class ResourceCreationUtils {
 
-	public static String ATT_UID = "jm007a";
-	public static String FIRST_NAME = "Julia";
-	public static String LAST_NAME = "Hendrix";
-	public static String DEFAULT_RESOURCE_NAME = "my-resource";
-	public static String DEFAULT_RESOURCE_VERSION = "1.0";
-	public static String DEFAULT_USER_ID = "jh0003";
+    public static String ATT_UID = "jm007a";
+    public static String FIRST_NAME = "Julia";
+    public static String LAST_NAME = "Hendrix";
+    public static String DEFAULT_RESOURCE_NAME = "my-resource";
+    public static String DEFAULT_RESOURCE_VERSION = "1.0";
+    public static String DEFAULT_USER_ID = "jh0003";
 
-	public static String MODIFIER_ATT_UID = "jk9990";
-	public static String MODIFIER_FIRST_NAME = "Roki";
-	public static String MODIFIER_LAST_NAME = "Balaboa";
+    public static String MODIFIER_ATT_UID = "jk9990";
+    public static String MODIFIER_FIRST_NAME = "Roki";
+    public static String MODIFIER_LAST_NAME = "Balaboa";
 
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/serialize/TestResourceSerialization.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/serialize/TestResourceSerialization.java
index 276558e..ba066d2 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/serialize/TestResourceSerialization.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/serialize/TestResourceSerialization.java
@@ -20,125 +20,135 @@
 
 package org.openecomp.sdc.be.model.serialize;
 
+import fj.data.Either;
+import org.openecomp.sdc.be.model.ComponentInstance;
 import org.openecomp.sdc.be.model.Resource;
+import org.openecomp.sdc.common.util.SerializationUtils;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
+import static org.junit.Assert.fail;
 
 public class TestResourceSerialization {
 
-	// @Test
-	public void findAllClassesUsedByResource() {
+    // @Test
+    public void findAllClassesUsedByResource() {
 
-		Set<Class> classesWithoutSerialzable = new HashSet<>();
-		Set<String> classestoIgnore = new HashSet<>();
-		classestoIgnore.add("java.util.List");
-		classestoIgnore.add("java.util.Map");
-		classestoIgnore.add("long");
+        Set<Class> classesWithoutSerialzable = new HashSet<>();
+        Set<String> classestoIgnore = new HashSet<>();
+        classestoIgnore.add("java.util.List");
+        classestoIgnore.add("java.util.Map");
+        classestoIgnore.add("long");
 
-		Set<Class> allClasses = new HashSet<>();
-		findAllClassesUsedByResource(Resource.class, allClasses);
-		ArrayList l;
-		for (Class clazz : allClasses) {
-			Class[] interfaces = clazz.getInterfaces();
-			if (interfaces != null) {
-				String collect = Arrays.stream(interfaces).map(p -> p.getName()).collect(Collectors.joining("\n"));
+        Set<Class> allClasses = new HashSet<>();
+        findAllClassesUsedByResource(Resource.class, allClasses);
+        ArrayList l;
+        for (Class clazz : allClasses) {
+            Class[] interfaces = clazz.getInterfaces();
+            if (interfaces != null) {
+                String collect = Arrays.stream(interfaces).map(Class::getName).collect(Collectors.joining("\n"));
 
-				Class orElse = Arrays.stream(interfaces).filter(p -> p.getName().equals("java.io.Serializable"))
-						.findAny().orElse(null);
-				if (orElse == null) {
-					classesWithoutSerialzable.add(clazz);
-				}
+                Class orElse = Arrays.stream(interfaces).filter(p -> p.getName().equals("java.io.Serializable"))
+                        .findAny().orElse(null);
+                if (orElse == null) {
+                    classesWithoutSerialzable.add(clazz);
+                }
 
-			}
-		}
+            }
+        }
 
-		List<Class> collect = classesWithoutSerialzable.stream()
-				.filter(p -> false == classestoIgnore.contains(p.getName())).collect(Collectors.toList());
+        List<Class> collect = classesWithoutSerialzable.stream()
+                                                       .filter(p -> !classestoIgnore.contains(p.getName())).collect(Collectors.toList());
 
-		if (collect != null) {
-			System.out.println(collect.stream().map(p -> p.getName()).collect(Collectors.joining("\n")));
-			assertEquals("check all classes implements Serializable", 0, collect.size());
-		}
+        if (collect != null) {
+            System.out.println(collect.stream().map(Class::getName).collect(Collectors.joining("\n")));
+            assertEquals("check all classes implements Serializable", 0, collect.size());
+        }
 
-	}
+    }
 
-	public void findAllClassesUsedByResource(Class clazz, Set<Class> allClasses) {
+    public void findAllClassesUsedByResource(Class clazz, Set<Class> allClasses) {
 
-		Class superclass = clazz.getSuperclass();
-		findAllClassesOfClass(clazz, allClasses);
+        Class superclass = clazz.getSuperclass();
+        findAllClassesOfClass(clazz, allClasses);
 
-		if (superclass != null) {
-			findAllClassesOfClass(superclass, allClasses);
-		}
+        if (superclass != null) {
+            findAllClassesOfClass(superclass, allClasses);
+        }
 
-	}
+    }
 
-	public void findAllClassesOfClass(Class clazz, Set<Class> allClasses) {
+    public void findAllClassesOfClass(Class clazz, Set<Class> allClasses) {
 
-		Field[] fields = clazz.getDeclaredFields();
-		if (fields != null) {
-			for (Field field : fields) {
-				String name = field.getName();
-				Class type = field.getType();
+        Field[] fields = clazz.getDeclaredFields();
+        if (fields != null) {
+            for (Field field : fields) {
+                String name = field.getName();
+                Class type = field.getType();
 
-				if (type.toString().contains(".List")) {
-					ParameterizedType stringListType = (ParameterizedType) field.getGenericType();
-					Class<?> stringListClass = (Class<?>) stringListType.getActualTypeArguments()[0];
-					allClasses.add(stringListClass);
-				}
+                if (type.toString().contains(".List")) {
+                    ParameterizedType stringListType = (ParameterizedType) field.getGenericType();
+                    Class<?> stringListClass = (Class<?>) stringListType.getActualTypeArguments()[0];
+                    allClasses.add(stringListClass);
+                }
 
-				if (type.toString().contains("java.util.Map")) {
-					ParameterizedType stringListType = (ParameterizedType) field.getGenericType();
+                if (type.toString().contains("java.util.Map")) {
+                    ParameterizedType stringListType = (ParameterizedType) field.getGenericType();
 
-					Type[] actualTypeArguments = stringListType.getActualTypeArguments();
-					if (actualTypeArguments != null) {
-						for (Type actualType : actualTypeArguments) {
+                    Type[] actualTypeArguments = stringListType.getActualTypeArguments();
+                    if (actualTypeArguments != null) {
+                        for (Type actualType : actualTypeArguments) {
 
-							String typeName = actualType.getTypeName();
-							// System.out.println("field " + name + "," +
-							// typeName);
+                            String typeName = actualType.getTypeName();
+                            // System.out.println("field " + name + "," +
+                            // typeName);
 
-							if (typeName.startsWith("java.util.List<")) {
-								String internalClass = typeName.replace("java.util.List<", "").replace(">", "");
-								// create class from string
-								Class myClass;
-								try {
-									myClass = Class.forName(internalClass);
-									allClasses.add(myClass);
-								} catch (ClassNotFoundException e) {
-									e.printStackTrace();
-									assertTrue("Failed to convert " + internalClass + " to class", false);
-								}
+                            if (typeName.startsWith("java.util.List<")) {
+                                String internalClass = typeName.replace("java.util.List<", "").replace(">", "");
+                                // create class from string
+                                Class myClass;
+                                try {
+                                    myClass = Class.forName(internalClass);
+                                    allClasses.add(myClass);
+                                } catch (ClassNotFoundException e) {
+                                    e.printStackTrace();
+                                    fail("Failed to convert " + internalClass + " to class");
+                                }
 
-							} else {
-								try {
-									Class myClass = Class.forName(typeName);
-									allClasses.add(myClass);
-								} catch (ClassNotFoundException e) {
-									e.printStackTrace();
-									assertTrue("Failed to convert " + typeName + " to class", false);
-								}
+                            } else {
+                                try {
+                                    Class myClass = Class.forName(typeName);
+                                    allClasses.add(myClass);
+                                } catch (ClassNotFoundException e) {
+                                    e.printStackTrace();
+                                    fail("Failed to convert " + typeName + " to class");
+                                }
 
-							}
-						}
-					}
+                            }
+                        }
+                    }
 
-				}
+                }
 
-				allClasses.add(type);
-			}
-		}
+                allClasses.add(type);
+            }
+        }
 
-	}
+    }
+    private boolean isClassImplementedSerialize(Class clazz) {
+        Type[] genericInterfaces = clazz.getGenericInterfaces();
+        if (genericInterfaces != null) {
+            Type orElse = Arrays.stream(genericInterfaces).filter(p -> p.getTypeName().equals("java.io.Serializable"))
+                    .findAny().orElse(null);
+            if (orElse != null) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/ToscaTypeTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/ToscaTypeTest.java
deleted file mode 100644
index 8028813..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/ToscaTypeTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.openecomp.sdc.be.model.tosca;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-
-public class ToscaTypeTest {
-
-	private ToscaType createTestSubject() {
-		return  ToscaType.BOOLEAN;
-	}
-
-	
-	@Test
-	public void testFromYamlTypeName() throws Exception {
-		String typeName = "";
-		ToscaType result;
-
-		// test 1
-		typeName = null;
-		result = ToscaType.fromYamlTypeName(typeName);
-		Assert.assertEquals(null, result);
-
-		// test 2
-		typeName = "";
-		result = ToscaType.fromYamlTypeName(typeName);
-		Assert.assertEquals(null, result);
-	}
-
-	
-	@Test
-	public void testIsValidValue() throws Exception {
-		ToscaType testSubject;
-		String value = "";
-		boolean result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.isValidValue(value);
-	}
-
-
-	
-	@Test
-	public void testConvert() throws Exception {
-		ToscaType testSubject;
-		String value = "";
-		Object result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.convert(value);
-	}
-
-	
-	@Test
-	public void testToString() throws Exception {
-		ToscaType testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.toString();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraintTest.java
deleted file mode 100644
index af8f28d..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraintTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.constraints;
-
-import org.junit.Test;
-
-
-public class EqualConstraintTest {
-
-	private EqualConstraint createTestSubject() {
-		return new EqualConstraint("");
-	}
-
-	
-
-	
-	@Test
-	public void testValidate() throws Exception {
-		EqualConstraint testSubject;
-		Object propertyValue = null;
-
-		// test 1
-		testSubject = createTestSubject();
-		propertyValue = null;
-		testSubject.validate(propertyValue);
-	}
-
-	
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraintTest.java
deleted file mode 100644
index 7d959d4..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraintTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.constraints;
-
-import org.junit.Test;
-
-public class GreaterThanConstraintTest {
-
-	private GreaterThanConstraint createTestSubject() {
-		return new GreaterThanConstraint("");
-	}
-
-
-
-	
-
-	
-	@Test
-	public void testGetGreaterThan() throws Exception {
-		GreaterThanConstraint testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getGreaterThan();
-	}
-
-	
-	@Test
-	public void testSetGreaterThan() throws Exception {
-		GreaterThanConstraint testSubject;
-		String greaterThan = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setGreaterThan(greaterThan);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraintTest.java
deleted file mode 100644
index e1df65e..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraintTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.constraints;
-
-import org.junit.Test;
-
-
-public class InRangeConstraintTest {
-
-	private InRangeConstraint createTestSubject() {
-		return new InRangeConstraint(null);
-	}
-
-	
-
-
-	
-	@Test
-	public void testGetRangeMinValue() throws Exception {
-		InRangeConstraint testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getRangeMinValue();
-	}
-
-	
-	@Test
-	public void testSetRangeMinValue() throws Exception {
-		InRangeConstraint testSubject;
-		String minValue = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setRangeMinValue(minValue);
-	}
-
-	
-	@Test
-	public void testGetRangeMaxValue() throws Exception {
-		InRangeConstraint testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getRangeMaxValue();
-	}
-
-	
-	@Test
-	public void testSetRangeMaxValue() throws Exception {
-		InRangeConstraint testSubject;
-		String maxValue = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setRangeMaxValue(maxValue);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraintTest.java
deleted file mode 100644
index 46a273b..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraintTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.constraints;
-
-import org.junit.Test;
-
-
-public class LengthConstraintTest {
-
-	private LengthConstraint createTestSubject() {
-		return new LengthConstraint();
-	}
-
-	
-
-
-	
-	@Test
-	public void testGetLength() throws Exception {
-		LengthConstraint testSubject;
-		Integer result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getLength();
-	}
-
-	
-	@Test
-	public void testSetLength() throws Exception {
-		LengthConstraint testSubject;
-		Integer length = 0;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setLength(length);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraintTest.java
deleted file mode 100644
index 54d8725..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraintTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.constraints;
-
-import org.junit.Test;
-
-
-public class LessOrEqualConstraintTest {
-
-	private LessOrEqualConstraint createTestSubject() {
-		return new LessOrEqualConstraint("");
-	}
-
-	
-
-	
-
-
-	
-	@Test
-	public void testGetLessOrEqual() throws Exception {
-		LessOrEqualConstraint testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getLessOrEqual();
-	}
-
-	
-	@Test
-	public void testSetLessOrEqual() throws Exception {
-		LessOrEqualConstraint testSubject;
-		String lessOrEqual = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setLessOrEqual(lessOrEqual);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraintTest.java
deleted file mode 100644
index 55c70c5..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraintTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.constraints;
-
-import org.junit.Test;
-
-
-public class MaxLengthConstraintTest {
-
-	private MaxLengthConstraint createTestSubject() {
-		return new MaxLengthConstraint(null);
-	}
-
-	
-	
-	@Test
-	public void testGetMaxLength() throws Exception {
-		MaxLengthConstraint testSubject;
-		Integer result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getMaxLength();
-	}
-
-	
-	@Test
-	public void testSetMaxLength() throws Exception {
-		MaxLengthConstraint testSubject;
-		Integer maxLength = 0;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setMaxLength(maxLength);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraintTest.java
deleted file mode 100644
index 1b8694f..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraintTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.constraints;
-
-import org.junit.Test;
-
-
-public class MinLengthConstraintTest {
-
-	private MinLengthConstraint createTestSubject() {
-		return new MinLengthConstraint(null);
-	}
-
-	
-
-
-	
-	@Test
-	public void testGetMinLength() throws Exception {
-		MinLengthConstraint testSubject;
-		Integer result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getMinLength();
-	}
-
-	
-	@Test
-	public void testSetMinLength() throws Exception {
-		MinLengthConstraint testSubject;
-		Integer minLength = 0;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setMinLength(minLength);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraintTest.java
deleted file mode 100644
index 07c657c..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraintTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.constraints;
-
-import org.junit.Test;
-
-
-public class PatternConstraintTest {
-
-	private PatternConstraint createTestSubject() {
-		return new PatternConstraint();
-	}
-
-	
-	@Test
-	public void testSetPattern() throws Exception {
-		PatternConstraint testSubject;
-		String pattern = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setPattern(pattern);
-	}
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraintTest.java
deleted file mode 100644
index 9b4c6b9..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraintTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.constraints;
-
-import java.util.List;
-
-import org.junit.Test;
-
-
-public class ValidValuesConstraintTest {
-
-	private ValidValuesConstraint createTestSubject() {
-		return new ValidValuesConstraint(null);
-	}
-
-	
-
-	
-
-
-	
-	@Test
-	public void testGetValidValues() throws Exception {
-		ValidValuesConstraint testSubject;
-		List<String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getValidValues();
-	}
-
-	
-	@Test
-	public void testSetValidValues() throws Exception {
-		ValidValuesConstraint testSubject;
-		List<String> validValues = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setValidValues(validValues);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverterTest.java
deleted file mode 100644
index 384c2d9..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverterTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
-
-public class BooleanConverterTest {
-
-	private BooleanConverter createTestSubject() {
-		return BooleanConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		BooleanConverter result;
-
-		// default test
-		result = BooleanConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testConvertToToscaValue() throws Exception {
-		BooleanConverter testSubject;
-		String value = "";
-		String innerType = "";
-		Map<String, DataTypeDefinition> dataTypes = null;
-		Object result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.convertToToscaValue(value, innerType, dataTypes);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java
index d542550..500ecfc 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java
@@ -1,19 +1,18 @@
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
+import com.google.gson.JsonObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.be.model.PropertyDefinition;
 
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.junit.Before;
-import org.junit.Test;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-
-import com.google.gson.JsonObject;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
 public class DataTypePropertyConverterTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverterTest.java
deleted file mode 100644
index d151f2a..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverterTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
-
-public class DefaultConverterTest {
-
-	private DefaultConverter createTestSubject() {
-		return DefaultConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		DefaultConverter result;
-
-		// default test
-		result = DefaultConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testConvert() throws Exception {
-		DefaultConverter testSubject;
-		String value = "";
-		String innerType = "";
-		Map<String, DataTypeDefinition> dataTypes = null;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.convert(value, innerType, dataTypes);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverterTest.java
deleted file mode 100644
index 1fb5c8c..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverterTest.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import org.junit.Test;
-
-
-public class FloatConverterTest {
-
-	private FloatConverter createTestSubject() {
-		return FloatConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		FloatConverter result;
-
-		// default test
-		result = FloatConverter.getInstance();
-	}
-
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverterTest.java
deleted file mode 100644
index 41a08b3..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverterTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import org.junit.Test;
-
-
-public class HeatBooleanConverterTest {
-
-	private HeatBooleanConverter createTestSubject() {
-		return HeatBooleanConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		HeatBooleanConverter result;
-
-		// default test
-		result = HeatBooleanConverter.getInstance();
-	}
-
-	
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverterTest.java
deleted file mode 100644
index 6361706..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverterTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import org.junit.Test;
-
-
-public class HeatCommaDelimitedListConverterTest {
-
-	private HeatCommaDelimitedListConverter createTestSubject() {
-		return HeatCommaDelimitedListConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		HeatCommaDelimitedListConverter result;
-
-		// default test
-		result = HeatCommaDelimitedListConverter.getInstance();
-	}
-
-	
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverterTest.java
deleted file mode 100644
index 1d13834..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverterTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import org.junit.Test;
-
-
-public class HeatJsonConverterTest {
-
-	private HeatJsonConverter createTestSubject() {
-		return HeatJsonConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		HeatJsonConverter result;
-
-		// default test
-		result = HeatJsonConverter.getInstance();
-	}
-
-	
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverterTest.java
deleted file mode 100644
index 93a54a7..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverterTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import org.junit.Test;
-
-
-public class HeatNumberConverterTest {
-
-	private HeatNumberConverter createTestSubject() {
-		return HeatNumberConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		HeatNumberConverter result;
-
-		// default test
-		result = HeatNumberConverter.getInstance();
-	}
-
-	
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverterTest.java
index 9f000a8..285dd9a 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverterTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverterTest.java
@@ -1,32 +1,16 @@
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import static org.junit.Assert.assertEquals;
-
 import org.junit.Test;
 
+import static org.junit.Assert.assertEquals;
+
 public class HeatStringConverterTest {
 
-	@Test
-	public void convertString_strWithQuotes_returnStringAsIs() {
-		String str = "'i'm string with \"quote\"'";
-		String convert = HeatStringConverter.getInstance().convert(str, null, null);
-		assertEquals(str, convert);
-	}
-
-	private HeatStringConverter createTestSubject() {
-		return HeatStringConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		HeatStringConverter result;
-
-		// default test
-		result = HeatStringConverter.getInstance();
-	}
-
-	
-
+    @Test
+    public void convertString_strWithQuotes_returnStringAsIs()  {
+        String str = "'i'm string with \"quote\"'";
+        String convert = HeatStringConverter.getInstance().convert(str, null, null);
+        assertEquals(str, convert);
+    }
 
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverterTest.java
deleted file mode 100644
index 8691ba0..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverterTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
-
-public class IntegerConverterTest {
-
-	private IntegerConverter createTestSubject() {
-		return IntegerConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		IntegerConverter result;
-
-		// default test
-		result = IntegerConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testConvertToToscaValue() throws Exception {
-		IntegerConverter testSubject;
-		String value = "";
-		String innerType = "";
-		Map<String, DataTypeDefinition> dataTypes = null;
-		Object result;
-
-		// test 1
-		testSubject = createTestSubject();
-		value = null;
-		result = testSubject.convertToToscaValue(value, innerType, dataTypes);
-		Assert.assertEquals(null, result);
-
-		// test 2
-		testSubject = createTestSubject();
-		value = "";
-		result = testSubject.convertToToscaValue(value, innerType, dataTypes);
-		Assert.assertEquals(null, result);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverterTest.java
deleted file mode 100644
index 537b895..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverterTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
-
-public class JsonConverterTest {
-
-	private JsonConverter createTestSubject() {
-		return JsonConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		JsonConverter result;
-
-		// default test
-		result = JsonConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testConvert() throws Exception {
-		JsonConverter testSubject;
-		String value = "";
-		String innerType = "";
-		Map<String, DataTypeDefinition> dataTypes = null;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.convert(value, innerType, dataTypes);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ListConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ListConverterTest.java
deleted file mode 100644
index 7002f81..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ListConverterTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import org.junit.Test;
-
-
-public class ListConverterTest {
-
-	private ListConverter createTestSubject() {
-		return new ListConverter();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		ListConverter result;
-
-		// default test
-		result = ListConverter.getInstance();
-	}
-
-	
-
-	
-	
-
-	
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverterTest.java
index fe37d3e..7ace040 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverterTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverterTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import java.util.Map;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class LowerCaseConverterTest {
 
 	private LowerCaseConverter createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/MapConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/MapConverterTest.java
deleted file mode 100644
index c837baa..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/MapConverterTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
-
-public class MapConverterTest {
-
-	private MapConverter createTestSubject() {
-		return new MapConverter();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		MapConverter result;
-
-		// default test
-		result = MapConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testConvert() throws Exception {
-		MapConverter testSubject;
-		String value = "";
-		String innerType = "";
-		Map<String, DataTypeDefinition> dataTypes = null;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.convert(value, innerType, dataTypes);
-	}
-
-	
-
-
-	
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertorTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertorTest.java
deleted file mode 100644
index 0cfdba8..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertorTest.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import org.junit.Test;
-
-public class StringConvertorTest {
-
-	private StringConvertor createTestSubject() {
-		return  StringConvertor.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		StringConvertor result;
-
-		// default test
-		result = StringConvertor.getInstance();
-	}
-
-	
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverterTest.java
deleted file mode 100644
index d5eab58..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverterTest.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import org.junit.Test;
-
-public class ToscaBooleanConverterTest {
-
-	private ToscaBooleanConverter createTestSubject() {
-		return  ToscaBooleanConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		ToscaBooleanConverter result;
-
-		// default test
-		result = ToscaBooleanConverter.getInstance();
-	}
-
-	
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverterTest.java
index 00ac263..7e9388e 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverterTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverterTest.java
@@ -1,12 +1,12 @@
 package org.openecomp.sdc.be.model.tosca.converters;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.junit.Assert.assertNull;
+import org.junit.Test;
 
 import java.util.Collections;
 
-import org.junit.Test;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.junit.Assert.assertNull;
 
 
 public class ToscaFloatConverterTest {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverterTest.java
deleted file mode 100644
index dc7526e..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverterTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
-
-public class ToscaJsonValueConverterTest {
-
-	private ToscaJsonValueConverter createTestSubject() {
-		return ToscaJsonValueConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		ToscaJsonValueConverter result;
-
-		// default test
-		result = ToscaJsonValueConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testConvertToToscaValue() throws Exception {
-		ToscaJsonValueConverter testSubject;
-		String value = "";
-		String innerType = "";
-		Map<String, DataTypeDefinition> dataTypes = null;
-		Object result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.convertToToscaValue(value, innerType, dataTypes);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverterTest.java
deleted file mode 100644
index 04ae069..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverterTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import org.junit.Test;
-
-
-public class ToscaListValueConverterTest {
-
-	private ToscaListValueConverter createTestSubject() {
-		return  ToscaListValueConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		ToscaListValueConverter result;
-
-		// default test
-		result = ToscaListValueConverter.getInstance();
-	}
-
-	
-
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertorTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertorTest.java
deleted file mode 100644
index a9909b8..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertorTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
-
-public class ToscaStringConvertorTest {
-
-	private ToscaStringConvertor createTestSubject() {
-		return ToscaStringConvertor.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		ToscaStringConvertor result;
-
-		// default test
-		result = ToscaStringConvertor.getInstance();
-	}
-
-	
-	@Test
-	public void testConvertToToscaValue() throws Exception {
-		ToscaStringConvertor testSubject;
-		String value = "";
-		String innerType = "";
-		Map<String, DataTypeDefinition> dataTypes = null;
-		Object result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.convertToToscaValue(value, innerType, dataTypes);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverterTest.java
deleted file mode 100644
index ea9a4a8..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverterTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.converters;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-
-
-public class ToscaValueDefaultConverterTest {
-
-	private ToscaValueDefaultConverter createTestSubject() {
-		return ToscaValueDefaultConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testGetInstance() throws Exception {
-		ToscaValueDefaultConverter result;
-
-		// default test
-		result = ToscaValueDefaultConverter.getInstance();
-	}
-
-	
-	@Test
-	public void testConvertToToscaValue() throws Exception {
-		ToscaValueDefaultConverter testSubject;
-		String value = "";
-		String innerType = "";
-		Map<String, DataTypeDefinition> dataTypes = null;
-		Object result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.convertToToscaValue(value, innerType, dataTypes);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidatorTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidatorTest.java
index aff1750..b33f1d2 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidatorTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidatorTest.java
@@ -20,51 +20,51 @@
 
 package org.openecomp.sdc.be.model.tosca.validators;
 
+import org.junit.Test;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import org.junit.Test;
-
 public class IntegerValidatorTest {
-	private static IntegerValidator validator = IntegerValidator.getInstance();
+    private static IntegerValidator validator = IntegerValidator.getInstance();
 
-	@Test
-	public void testIntegerValidatorDecimal() {
-		assertTrue(validator.isValid(null, null));
-		assertTrue(validator.isValid("", null));
-		assertTrue(validator.isValid("0", null));
-		assertTrue(validator.isValid("+0", null));
-		assertTrue(validator.isValid("-0", null));
-		assertTrue(validator.isValid("+65465", null));
-		assertTrue(validator.isValid("-65465", null));
-		assertTrue(validator.isValid("2147483647", null));
-		assertFalse(validator.isValid("2147483648", null));
-		assertTrue(validator.isValid("-2147483648", null));
-		assertFalse(validator.isValid("-2147483649", null));
-	}
+    @Test
+    public void testIntegerValidatorDecimal() {
+        assertTrue(validator.isValid(null, null));
+        assertTrue(validator.isValid("", null));
+        assertTrue(validator.isValid("0", null));
+        assertTrue(validator.isValid("+0", null));
+        assertTrue(validator.isValid("-0", null));
+        assertTrue(validator.isValid("+65465", null));
+        assertTrue(validator.isValid("-65465", null));
+        assertTrue(validator.isValid("2147483647", null));
+        assertFalse(validator.isValid("2147483648", null));
+        assertTrue(validator.isValid("-2147483648", null));
+        assertFalse(validator.isValid("-2147483649", null));
+    }
 
-	@Test
-	public void testIntegerValidatorHexa() {
-		assertTrue(validator.isValid("-0xadc", null));
-		assertTrue(validator.isValid("+0xadf", null));
-		assertTrue(validator.isValid("0x7FFFFFFF", null));
-		assertFalse(validator.isValid("0x80000000", null));
-		assertTrue(validator.isValid("-0x80000000", null));
-		assertFalse(validator.isValid("-0x80000001", null));
-	}
+    @Test
+    public void testIntegerValidatorHexa() {
+        assertTrue(validator.isValid("-0xadc", null));
+        assertTrue(validator.isValid("+0xadf", null));
+        assertTrue(validator.isValid("0x7FFFFFFF", null));
+        assertFalse(validator.isValid("0x80000000", null));
+        assertTrue(validator.isValid("-0x80000000", null));
+        assertFalse(validator.isValid("-0x80000001", null));
+    }
 
-	public void testIntegerValidatorOctal() {
-		assertTrue(validator.isValid("0o545435", null));
-		assertTrue(validator.isValid("-0o545435", null));
-		assertTrue(validator.isValid("0o17777777777", null));
-		assertFalse(validator.isValid("0o20000000000", null));
-		assertTrue(validator.isValid("-0o20000000000", null));
-		assertFalse(validator.isValid("-0o20000000001", null));
-	}
+    public void testIntegerValidatorOctal() {
+        assertTrue(validator.isValid("0o545435", null));
+        assertTrue(validator.isValid("-0o545435", null));
+        assertTrue(validator.isValid("0o17777777777", null));
+        assertFalse(validator.isValid("0o20000000000", null));
+        assertTrue(validator.isValid("-0o20000000000", null));
+        assertFalse(validator.isValid("-0o20000000001", null));
+    }
 
-	@Test
-	public void testIntegerValidatorIncorrect() {
-		assertFalse(validator.isValid("-2.147483649", null));
-		assertFalse(validator.isValid("dsfasf342342", null));
-	}
+    @Test
+    public void testIntegerValidatorIncorrect() {
+        assertFalse(validator.isValid("-2.147483649", null));
+        assertFalse(validator.isValid("dsfasf342342", null));
+    }
 }
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/MapValidatorTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/MapValidatorTest.java
index c82894f..4fa64d6 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/MapValidatorTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/MapValidatorTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import static org.junit.Assert.assertFalse;
+import org.junit.Test;
 
 import java.util.Collections;
 
-import org.junit.Test;
+import static org.junit.Assert.assertFalse;
 
 public class MapValidatorTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidatorTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidatorTest.java
index 3070c3d..dafbab8 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidatorTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidatorTest.java
@@ -1,10 +1,10 @@
 package org.openecomp.sdc.be.model.tosca.validators;
 
-import java.util.Map;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 
+import java.util.Map;
+
 public class ToscaBooleanValidatorTest {
 
 	private ToscaBooleanValidator createTestSubject() {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersionTest.java
deleted file mode 100644
index 5e1d378..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersionTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.version;
-
-import org.junit.Test;
-
-
-public class ComparableVersionTest {
-
-	private ComparableVersion createTestSubject() {
-		return new ComparableVersion("");
-	}
-
-	
-	@Test
-	public void testParseVersion() throws Exception {
-		ComparableVersion testSubject;
-		String version = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.parseVersion(version);
-	}
-
-	
-
-
-	
-
-
-	
-	@Test
-	public void testToString() throws Exception {
-		ComparableVersion testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.toString();
-	}
-
-	
-	@Test
-	public void testEquals() throws Exception {
-		ComparableVersion testSubject;
-		Object o = null;
-		boolean result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.equals(o);
-	}
-
-	
-	@Test
-	public void testHashCode() throws Exception {
-		ComparableVersion testSubject;
-		int result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.hashCode();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/version/VersionTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/version/VersionTest.java
deleted file mode 100644
index cf84890..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/version/VersionTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.openecomp.sdc.be.model.tosca.version;
-
-import org.junit.Test;
-
-public class VersionTest {
-
-	private Version createTestSubject() {
-		return new Version("");
-	}
-
-	
-	@Test
-	public void testHashCode() throws Exception {
-		Version testSubject;
-		int result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.hashCode();
-	}
-
-	
-	@Test
-	public void testEquals() throws Exception {
-		Version testSubject;
-		Object other = null;
-		boolean result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.equals(other);
-	}
-
-	
-	@Test
-	public void testCompareTo() throws Exception {
-		Version testSubject;
-		Version otherVersion = null;
-		int result;
-
-		// default test
-		testSubject = createTestSubject();
-	}
-
-	
-	@Test
-	public void testGetMajorVersion() throws Exception {
-		Version testSubject;
-		int result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getMajorVersion();
-	}
-
-	
-	@Test
-	public void testGetMinorVersion() throws Exception {
-		Version testSubject;
-		int result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getMinorVersion();
-	}
-
-	
-	@Test
-	public void testGetIncrementalVersion() throws Exception {
-		Version testSubject;
-		int result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getIncrementalVersion();
-	}
-
-	
-	@Test
-	public void testGetBuildNumber() throws Exception {
-		Version testSubject;
-		int result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getBuildNumber();
-	}
-
-	
-	@Test
-	public void testGetQualifier() throws Exception {
-		Version testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getQualifier();
-	}
-
-	
-	@Test
-	public void testParseVersion() throws Exception {
-		Version testSubject;
-		String version = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.parseVersion(version);
-	}
-
-	
-	@Test
-	public void testGetNextIntegerToken() throws Exception {
-		Integer result;
-
-		// default test
-	}
-
-	
-	@Test
-	public void testToString() throws Exception {
-		Version testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.toString();
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiCategoriesTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiCategoriesTest.java
deleted file mode 100644
index c0d69fa..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiCategoriesTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.openecomp.sdc.be.ui.model;
-
-import java.util.List;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.model.category.CategoryDefinition;
-
-
-public class UiCategoriesTest {
-
-	private UiCategories createTestSubject() {
-		return new UiCategories();
-	}
-
-	
-	@Test
-	public void testGetResourceCategories() throws Exception {
-		UiCategories testSubject;
-		List<CategoryDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getResourceCategories();
-	}
-
-	
-	@Test
-	public void testSetResourceCategories() throws Exception {
-		UiCategories testSubject;
-		List<CategoryDefinition> resourceCategories = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setResourceCategories(resourceCategories);
-	}
-
-	
-	@Test
-	public void testGetServiceCategories() throws Exception {
-		UiCategories testSubject;
-		List<CategoryDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getServiceCategories();
-	}
-
-	
-	@Test
-	public void testSetServiceCategories() throws Exception {
-		UiCategories testSubject;
-		List<CategoryDefinition> serviceCategories = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setServiceCategories(serviceCategories);
-	}
-
-	
-	@Test
-	public void testGetProductCategories() throws Exception {
-		UiCategories testSubject;
-		List<CategoryDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getProductCategories();
-	}
-
-	
-	@Test
-	public void testSetProductCategories() throws Exception {
-		UiCategories testSubject;
-		List<CategoryDefinition> productCategories = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setProductCategories(productCategories);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransferTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransferTest.java
deleted file mode 100644
index 4fd0ccc..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransferTest.java
+++ /dev/null
@@ -1,444 +0,0 @@
-package org.openecomp.sdc.be.ui.model;
-
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
-import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-import org.openecomp.sdc.be.model.CapabilityDefinition;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceInput;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.InputDefinition;
-import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
-import org.openecomp.sdc.be.model.RequirementDefinition;
-import org.openecomp.sdc.be.model.category.CategoryDefinition;
-
-
-public class UiComponentDataTransferTest {
-
-	private UiComponentDataTransfer createTestSubject() {
-		return new UiComponentDataTransfer();
-	}
-
-	
-	@Test
-	public void testGetArtifacts() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, ArtifactDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getArtifacts();
-	}
-
-	
-	@Test
-	public void testSetArtifacts() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, ArtifactDefinition> artifacts = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setArtifacts(artifacts);
-	}
-
-	
-	@Test
-	public void testGetDeploymentArtifacts() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, ArtifactDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getDeploymentArtifacts();
-	}
-
-	
-	@Test
-	public void testSetDeploymentArtifacts() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, ArtifactDefinition> deploymentArtifacts = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setDeploymentArtifacts(deploymentArtifacts);
-	}
-
-	
-	@Test
-	public void testGetToscaArtifacts() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, ArtifactDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getToscaArtifacts();
-	}
-
-	
-	@Test
-	public void testSetToscaArtifacts() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, ArtifactDefinition> toscaArtifacts = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setToscaArtifacts(toscaArtifacts);
-	}
-
-	
-	@Test
-	public void testGetCategories() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<CategoryDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCategories();
-	}
-
-	
-	@Test
-	public void testSetCategories() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<CategoryDefinition> categories = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCategories(categories);
-	}
-
-	
-	@Test
-	public void testGetCreatorUserId() throws Exception {
-		UiComponentDataTransfer testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCreatorUserId();
-	}
-
-	
-	@Test
-	public void testSetCreatorUserId() throws Exception {
-		UiComponentDataTransfer testSubject;
-		String creatorUserId = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCreatorUserId(creatorUserId);
-	}
-
-	
-	@Test
-	public void testGetCreatorFullName() throws Exception {
-		UiComponentDataTransfer testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCreatorFullName();
-	}
-
-	
-	@Test
-	public void testSetCreatorFullName() throws Exception {
-		UiComponentDataTransfer testSubject;
-		String creatorFullName = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCreatorFullName(creatorFullName);
-	}
-
-	
-	@Test
-	public void testGetLastUpdaterUserId() throws Exception {
-		UiComponentDataTransfer testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getLastUpdaterUserId();
-	}
-
-	
-	@Test
-	public void testSetLastUpdaterUserId() throws Exception {
-		UiComponentDataTransfer testSubject;
-		String lastUpdaterUserId = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setLastUpdaterUserId(lastUpdaterUserId);
-	}
-
-	
-	@Test
-	public void testGetLastUpdaterFullName() throws Exception {
-		UiComponentDataTransfer testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getLastUpdaterFullName();
-	}
-
-	
-	@Test
-	public void testSetLastUpdaterFullName() throws Exception {
-		UiComponentDataTransfer testSubject;
-		String lastUpdaterFullName = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setLastUpdaterFullName(lastUpdaterFullName);
-	}
-
-	
-	@Test
-	public void testGetComponentType() throws Exception {
-		UiComponentDataTransfer testSubject;
-		ComponentTypeEnum result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getComponentType();
-	}
-
-	
-	@Test
-	public void testSetComponentType() throws Exception {
-		UiComponentDataTransfer testSubject;
-		ComponentTypeEnum componentType = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setComponentType(componentType);
-	}
-
-	
-	@Test
-	public void testGetComponentInstances() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<ComponentInstance> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getComponentInstances();
-	}
-
-	
-	@Test
-	public void testSetComponentInstances() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<ComponentInstance> componentInstances = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setComponentInstances(componentInstances);
-	}
-
-	
-	@Test
-	public void testGetComponentInstancesRelations() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<RequirementCapabilityRelDef> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getComponentInstancesRelations();
-	}
-
-	
-	@Test
-	public void testSetComponentInstancesRelations() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<RequirementCapabilityRelDef> componentInstancesRelations = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setComponentInstancesRelations(componentInstancesRelations);
-	}
-
-	
-	@Test
-	public void testGetComponentInstancesInputs() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, List<ComponentInstanceInput>> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getComponentInstancesInputs();
-	}
-
-	
-	@Test
-	public void testSetComponentInstancesInputs() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, List<ComponentInstanceInput>> componentInstancesInputs = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setComponentInstancesInputs(componentInstancesInputs);
-	}
-
-	
-	@Test
-	public void testGetComponentInstancesProperties() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, List<ComponentInstanceProperty>> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getComponentInstancesProperties();
-	}
-
-	
-	@Test
-	public void testSetComponentInstancesProperties() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setComponentInstancesProperties(componentInstancesProperties);
-	}
-
-	
-	@Test
-	public void testGetComponentInstancesAttributes() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, List<ComponentInstanceProperty>> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getComponentInstancesAttributes();
-	}
-
-	
-	@Test
-	public void testSetComponentInstancesAttributes() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, List<ComponentInstanceProperty>> componentInstancesAttributes = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setComponentInstancesAttributes(componentInstancesAttributes);
-	}
-
-	
-	@Test
-	public void testGetCapabilities() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, List<CapabilityDefinition>> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCapabilities();
-	}
-
-	
-	@Test
-	public void testSetCapabilities() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, List<CapabilityDefinition>> capabilities = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCapabilities(capabilities);
-	}
-
-	
-	@Test
-	public void testGetRequirements() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, List<RequirementDefinition>> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getRequirements();
-	}
-
-	
-	@Test
-	public void testSetRequirements() throws Exception {
-		UiComponentDataTransfer testSubject;
-		Map<String, List<RequirementDefinition>> requirements = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setRequirements(requirements);
-	}
-
-	
-	@Test
-	public void testGetInputs() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<InputDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getInputs();
-	}
-
-	
-	@Test
-	public void testSetInputs() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<InputDefinition> inputs = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setInputs(inputs);
-	}
-
-	
-	@Test
-	public void testGetGroups() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<GroupDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getGroups();
-	}
-
-	
-	@Test
-	public void testSetGroups() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<GroupDefinition> groups = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setGroups(groups);
-	}
-
-	
-	@Test
-	public void testGetAdditionalInformation() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<AdditionalInformationDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getAdditionalInformation();
-	}
-
-	
-	@Test
-	public void testSetAdditionalInformation() throws Exception {
-		UiComponentDataTransfer testSubject;
-		List<AdditionalInformationDefinition> additionalInformation = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setAdditionalInformation(additionalInformation);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransferTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransferTest.java
deleted file mode 100644
index e50b6c4..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransferTest.java
+++ /dev/null
@@ -1,193 +0,0 @@
-package org.openecomp.sdc.be.ui.model;
-
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
-import org.openecomp.sdc.be.model.InterfaceDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-
-
-public class UiResourceDataTransferTest {
-
-	private UiResourceDataTransfer createTestSubject() {
-		return new UiResourceDataTransfer();
-	}
-
-	
-	@Test
-	public void testGetAdditionalInformation() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<AdditionalInformationDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getAdditionalInformation();
-	}
-
-	
-	@Test
-	public void testSetAdditionalInformation() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<AdditionalInformationDefinition> additionalInformation = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setAdditionalInformation(additionalInformation);
-	}
-
-	
-	@Test
-	public void testGetMetadata() throws Exception {
-		UiResourceDataTransfer testSubject;
-		UiResourceMetadata result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getMetadata();
-	}
-
-	
-	@Test
-	public void testSetMetadata() throws Exception {
-		UiResourceDataTransfer testSubject;
-		UiResourceMetadata metadata = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setMetadata(metadata);
-	}
-
-	
-	@Test
-	public void testGetDerivedFrom() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getDerivedFrom();
-	}
-
-	
-	@Test
-	public void testSetDerivedFrom() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<String> derivedFrom = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setDerivedFrom(derivedFrom);
-	}
-
-	
-	@Test
-	public void testGetDerivedList() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getDerivedList();
-	}
-
-	
-	@Test
-	public void testSetDerivedList() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<String> derivedList = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setDerivedList(derivedList);
-	}
-
-	
-	@Test
-	public void testGetProperties() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<PropertyDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getProperties();
-	}
-
-	
-	@Test
-	public void testSetProperties() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<PropertyDefinition> properties = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setProperties(properties);
-	}
-
-	
-	@Test
-	public void testGetAttributes() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<PropertyDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getAttributes();
-	}
-
-	
-	@Test
-	public void testSetAttributes() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<PropertyDefinition> attributes = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setAttributes(attributes);
-	}
-
-	
-	@Test
-	public void testGetInterfaces() throws Exception {
-		UiResourceDataTransfer testSubject;
-		Map<String, InterfaceDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getInterfaces();
-	}
-
-	
-	@Test
-	public void testSetInterfaces() throws Exception {
-		UiResourceDataTransfer testSubject;
-		Map<String, InterfaceDefinition> interfaces = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setInterfaces(interfaces);
-	}
-
-	
-	@Test
-	public void testGetDefaultCapabilities() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getDefaultCapabilities();
-	}
-
-	
-	@Test
-	public void testSetDefaultCapabilities() throws Exception {
-		UiResourceDataTransfer testSubject;
-		List<String> defaultCapabilities = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setDefaultCapabilities(defaultCapabilities);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiResourceMetadataTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiResourceMetadataTest.java
deleted file mode 100644
index eb5ccff..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiResourceMetadataTest.java
+++ /dev/null
@@ -1,213 +0,0 @@
-package org.openecomp.sdc.be.ui.model;
-
-import java.util.List;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
-import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
-
-
-public class UiResourceMetadataTest {
-
-	private UiResourceMetadata createTestSubject() {
-		return new UiResourceMetadata(null, null, new ResourceMetadataDataDefinition());
-	}
-
-	
-	@Test
-	public void testGetDerivedFrom() throws Exception {
-		UiResourceMetadata testSubject;
-		List<String> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getDerivedFrom();
-	}
-
-	
-	@Test
-	public void testSetDerivedFrom() throws Exception {
-		UiResourceMetadata testSubject;
-		List<String> derivedFrom = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setDerivedFrom(derivedFrom);
-	}
-
-	
-	@Test
-	public void testGetVendorName() throws Exception {
-		UiResourceMetadata testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getVendorName();
-	}
-
-	
-	@Test
-	public void testSetVendorName() throws Exception {
-		UiResourceMetadata testSubject;
-		String vendorName = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setVendorName(vendorName);
-	}
-
-	
-	@Test
-	public void testGetVendorRelease() throws Exception {
-		UiResourceMetadata testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getVendorRelease();
-	}
-
-	
-	@Test
-	public void testSetVendorRelease() throws Exception {
-		UiResourceMetadata testSubject;
-		String vendorRelease = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setVendorRelease(vendorRelease);
-	}
-
-	
-	@Test
-	public void testGetResourceVendorModelNumber() throws Exception {
-		UiResourceMetadata testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getResourceVendorModelNumber();
-	}
-
-	
-	@Test
-	public void testSetResourceVendorModelNumber() throws Exception {
-		UiResourceMetadata testSubject;
-		String resourceVendorModelNumber = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setResourceVendorModelNumber(resourceVendorModelNumber);
-	}
-
-	
-	@Test
-	public void testGetResourceType() throws Exception {
-		UiResourceMetadata testSubject;
-		ResourceTypeEnum result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getResourceType();
-	}
-
-	
-	@Test
-	public void testSetResourceType() throws Exception {
-		UiResourceMetadata testSubject;
-		ResourceTypeEnum resourceType = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setResourceType(resourceType);
-	}
-
-	
-	@Test
-	public void testGetIsAbstract() throws Exception {
-		UiResourceMetadata testSubject;
-		Boolean result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getIsAbstract();
-	}
-
-	
-	@Test
-	public void testSetIsAbstract() throws Exception {
-		UiResourceMetadata testSubject;
-		Boolean isAbstract = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setIsAbstract(isAbstract);
-	}
-
-	
-	@Test
-	public void testGetCost() throws Exception {
-		UiResourceMetadata testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getCost();
-	}
-
-	
-	@Test
-	public void testSetCost() throws Exception {
-		UiResourceMetadata testSubject;
-		String cost = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setCost(cost);
-	}
-
-	
-	@Test
-	public void testGetLicenseType() throws Exception {
-		UiResourceMetadata testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getLicenseType();
-	}
-
-	
-	@Test
-	public void testSetLicenseType() throws Exception {
-		UiResourceMetadata testSubject;
-		String licenseType = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setLicenseType(licenseType);
-	}
-
-	
-	@Test
-	public void testGetToscaResourceName() throws Exception {
-		UiResourceMetadata testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getToscaResourceName();
-	}
-
-	
-	@Test
-	public void testSetToscaResourceName() throws Exception {
-		UiResourceMetadata testSubject;
-		String toscaResourceName = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setToscaResourceName(toscaResourceName);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiServiceDataTransferTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiServiceDataTransferTest.java
deleted file mode 100644
index 3bb5aa1..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiServiceDataTransferTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.openecomp.sdc.be.ui.model;
-
-import java.util.Map;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-
-
-public class UiServiceDataTransferTest {
-
-	private UiServiceDataTransfer createTestSubject() {
-		return new UiServiceDataTransfer();
-	}
-
-	
-	@Test
-	public void testGetMetadata() throws Exception {
-		UiServiceDataTransfer testSubject;
-		UiServiceMetadata result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getMetadata();
-	}
-
-	
-	@Test
-	public void testSetMetadata() throws Exception {
-		UiServiceDataTransfer testSubject;
-		UiServiceMetadata metadata = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setMetadata(metadata);
-	}
-
-	
-	@Test
-	public void testGetServiceApiArtifacts() throws Exception {
-		UiServiceDataTransfer testSubject;
-		Map<String, ArtifactDefinition> result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getServiceApiArtifacts();
-	}
-
-	
-	@Test
-	public void testSetServiceApiArtifacts() throws Exception {
-		UiServiceDataTransfer testSubject;
-		Map<String, ArtifactDefinition> serviceApiArtifacts = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setServiceApiArtifacts(serviceApiArtifacts);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiServiceMetadataTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiServiceMetadataTest.java
deleted file mode 100644
index 712053c..0000000
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/model/UiServiceMetadataTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package org.openecomp.sdc.be.ui.model;
-
-import org.junit.Test;
-import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
-
-
-public class UiServiceMetadataTest {
-
-	private UiServiceMetadata createTestSubject() {
-		return new UiServiceMetadata(null, new ServiceMetadataDataDefinition());
-	}
-
-	
-	@Test
-	public void testGetDistributionStatus() throws Exception {
-		UiServiceMetadata testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getDistributionStatus();
-	}
-
-	
-	@Test
-	public void testSetDistributionStatus() throws Exception {
-		UiServiceMetadata testSubject;
-		String distributionStatus = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setDistributionStatus(distributionStatus);
-	}
-
-	
-	@Test
-	public void testGetEcompGeneratedNaming() throws Exception {
-		UiServiceMetadata testSubject;
-		Boolean result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getEcompGeneratedNaming();
-	}
-
-	
-	@Test
-	public void testSetEcompGeneratedNaming() throws Exception {
-		UiServiceMetadata testSubject;
-		Boolean ecompGeneratedNaming = null;
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setEcompGeneratedNaming(ecompGeneratedNaming);
-	}
-
-	
-	@Test
-	public void testGetNamingPolicy() throws Exception {
-		UiServiceMetadata testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getNamingPolicy();
-	}
-
-	
-	@Test
-	public void testSetNamingPolicy() throws Exception {
-		UiServiceMetadata testSubject;
-		String namingPolicy = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setNamingPolicy(namingPolicy);
-	}
-
-	
-	@Test
-	public void testGetServiceType() throws Exception {
-		UiServiceMetadata testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getServiceType();
-	}
-
-	
-	@Test
-	public void testSetServiceType() throws Exception {
-		UiServiceMetadata testSubject;
-		String serviceType = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setServiceType(serviceType);
-	}
-
-	
-	@Test
-	public void testGetServiceRole() throws Exception {
-		UiServiceMetadata testSubject;
-		String result;
-
-		// default test
-		testSubject = createTestSubject();
-		result = testSubject.getServiceRole();
-	}
-
-	
-	@Test
-	public void testSetServiceRole() throws Exception {
-		UiServiceMetadata testSubject;
-		String serviceRole = "";
-
-		// default test
-		testSubject = createTestSubject();
-		testSubject.setServiceRole(serviceRole);
-	}
-}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/unittests/utils/FactoryUtilsTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/unittests/utils/FactoryUtilsTest.java
index 53ed776..14918be 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/unittests/utils/FactoryUtilsTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/unittests/utils/FactoryUtilsTest.java
@@ -1,21 +1,11 @@
 package org.openecomp.sdc.be.unittests.utils;
 
-import java.util.List;
-
 import org.junit.Test;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
-import org.openecomp.sdc.be.model.CapabilityDefinition;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.RequirementDefinition;
-import org.openecomp.sdc.be.model.Resource;
-import org.openecomp.sdc.be.resources.data.CapabilityData;
-import org.openecomp.sdc.be.resources.data.CapabilityInstData;
-import org.openecomp.sdc.be.resources.data.PropertyData;
-import org.openecomp.sdc.be.resources.data.PropertyValueData;
-import org.openecomp.sdc.be.resources.data.RequirementData;
-import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
+import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.resources.data.*;
+
+import java.util.List;
 
 public class FactoryUtilsTest {
 
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/unittests/utils/ModelConfDependentTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/unittests/utils/ModelConfDependentTest.java
index 2135b66..c25fb45 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/unittests/utils/ModelConfDependentTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/unittests/utils/ModelConfDependentTest.java
@@ -3,7 +3,7 @@
 import org.junit.BeforeClass;
 import org.openecomp.sdc.common.test.BaseConfDependent;
 
-public class ModelConfDependentTest extends BaseConfDependent {
+public abstract class ModelConfDependentTest extends BaseConfDependent {
 	@BeforeClass
 	public static void setupBeforeClass() {
         componentName = "catalog-model";
diff --git a/catalog-model/src/test/resources/application-context-test.xml b/catalog-model/src/test/resources/application-context-test.xml
index ccde197..2447774 100644
--- a/catalog-model/src/test/resources/application-context-test.xml
+++ b/catalog-model/src/test/resources/application-context-test.xml
@@ -1,9 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
-	xmlns:util="http://www.springframework.org/schema/util"
-	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
-           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
            
 
   <context:component-scan
diff --git a/catalog-model/src/test/resources/config/catalog-model/configuration.yaml b/catalog-model/src/test/resources/config/catalog-model/configuration.yaml
index f948f6e..c95715d 100644
--- a/catalog-model/src/test/resources/config/catalog-model/configuration.yaml
+++ b/catalog-model/src/test/resources/config/catalog-model/configuration.yaml
@@ -23,7 +23,7 @@
 
 version: 1.1.0
 released: 2012-11-30
-toscaConformanceLevel: 5.0
+toscaConformanceLevel: 8.0
 minToscaConformanceLevel: 3.0
 
 titanCfgFile: /home/vagrant/catalog-be/config/catalog-be/titan.properties
diff --git a/catalog-model/src/test/resources/config/configuration.yaml b/catalog-model/src/test/resources/config/configuration.yaml
index f948f6e..c95715d 100644
--- a/catalog-model/src/test/resources/config/configuration.yaml
+++ b/catalog-model/src/test/resources/config/configuration.yaml
@@ -23,7 +23,7 @@
 
 version: 1.1.0
 released: 2012-11-30
-toscaConformanceLevel: 5.0
+toscaConformanceLevel: 8.0
 minToscaConformanceLevel: 3.0
 
 titanCfgFile: /home/vagrant/catalog-be/config/catalog-be/titan.properties
