[SDC-29] catalog 1707 rebase commit.

Change-Id: I43c3dc5cf44abf5da817649bc738938a3e8388c1
Signed-off-by: Michael Lando <ml636r@att.com>
diff --git a/catalog-ui/src/app/utils/artifacts-utils.ts b/catalog-ui/src/app/utils/artifacts-utils.ts
new file mode 100644
index 0000000..b52fe6f
--- /dev/null
+++ b/catalog-ui/src/app/utils/artifacts-utils.ts
@@ -0,0 +1,104 @@
+import {ArtifactModel} from "../models/artifacts";
+import {IArtifactResourceFormViewModelScope} from "../view-models/forms/artifact-form/artifact-form-view-model";
+import {Component} from "../models/components/component";
+import {ArtifactGroupType, ArtifactType} from "./constants";
+export class ArtifactsUtils {
+
+    static '$inject' = [
+        '$filter'
+    ];
+
+    constructor(private $filter:ng.IFilterService) {
+
+    }
+
+    public getArtifactTypeByState(currentState:string):string {
+        switch (currentState) {
+            case "workspace.composition.lifecycle":
+                return "interface";
+            case "workspace.composition.api":
+                return "api";
+            case "workspace.deployment_artifacts":
+            case "workspace.composition.deployment":
+                return "deployment";
+            case "workspace.composition.artifacts":
+                return "informational";
+            default:
+                return "informational";
+        }
+    }
+
+    public getTitle(artifactType:string, selectedComponent:Component):string {
+        switch (artifactType) {
+            case "interface":
+                return "Lifecycle Management";
+            case "api":
+                return "API Artifacts";
+            case "deployment":
+                return "Deployment Artifacts";
+            case "informational":
+                return "Informational Artifacts";
+            default:
+                if (!selectedComponent) {
+                    return "";
+                } else {
+                    return this.$filter("resourceName")(selectedComponent.name) + ' Artifacts';
+                }
+        }
+    }
+
+    public setArtifactType = (artifact:ArtifactModel, artifactType:string):void => {
+        switch (artifactType) {
+            case "api":
+                artifact.artifactGroupType = ArtifactGroupType.SERVICE_API;
+                break;
+            case "deployment":
+                artifact.artifactGroupType = ArtifactGroupType.DEPLOYMENT;
+                break;
+            default:
+                artifact.artifactGroupType = ArtifactGroupType.INFORMATION;
+                break;
+        }
+    };
+
+    public isLicenseType = (artifactType:string):boolean => {
+        let isLicense:boolean = false;
+
+        if (ArtifactType.VENDOR_LICENSE === artifactType || ArtifactType.VF_LICENSE === artifactType) {
+            isLicense = true;
+        }
+
+        return isLicense;
+    };
+
+    public removeArtifact = (artifact:ArtifactModel, artifactsArr:Array<ArtifactModel>):void => {
+
+        if (!artifact.mandatory && (ArtifactGroupType.INFORMATION == artifact.artifactGroupType ||
+            ArtifactGroupType.DEPLOYMENT == artifact.artifactGroupType)) {
+            _.remove(artifactsArr, {uniqueId: artifact.uniqueId});
+        }
+        else {
+            let artifactToDelete = _.find(artifactsArr, {uniqueId: artifact.uniqueId});
+
+            delete artifactToDelete.esId;
+            delete artifactToDelete.description;
+            delete artifactToDelete.artifactName;
+            delete artifactToDelete.apiUrl;
+        }
+    };
+
+    public addAnotherAfterSave(scope:IArtifactResourceFormViewModelScope) {
+        let newArtifact = new ArtifactModel();
+        this.setArtifactType(newArtifact, scope.artifactType);
+        scope.editArtifactResourceModel.artifactResource = newArtifact;
+
+        scope.forms.editForm['description'].$setPristine();
+        if (scope.forms.editForm['artifactLabel']) {
+            scope.forms.editForm['artifactLabel'].$setPristine();
+        }
+        if (scope.forms.editForm['type']) {
+            scope.forms.editForm['type'].$setPristine();
+        }
+
+    }
+}
diff --git a/catalog-ui/src/app/utils/change-lifecycle-state-handler.ts b/catalog-ui/src/app/utils/change-lifecycle-state-handler.ts
new file mode 100644
index 0000000..dc59e3b
--- /dev/null
+++ b/catalog-ui/src/app/utils/change-lifecycle-state-handler.ts
@@ -0,0 +1,163 @@
+import {ComponentFactory} from "./component-factory";
+import {Component, Service,IAppMenu, IAppConfigurtaion} from "../models";
+import {IEmailModalModel, IEmailModalModel_Email, IEmailModalModel_Data} from "../view-models/modals/email-modal/email-modal-view-model";
+import {AsdcComment} from "../models/comments";
+import {ModalsHandler} from "./modals-handler";
+import {ServiceServiceNg2} from "../ng2/services/component-services/service.service";
+
+/**
+ * Created by obarda on 2/11/2016.
+ */
+
+export class ChangeLifecycleStateHandler {
+
+    static '$inject' = [
+        'sdcConfig',
+        'sdcMenu',
+        'ComponentFactory',
+        '$filter',
+        'ModalsHandler',
+        'ServiceServiceNg2'
+    ];
+
+    constructor(private sdcConfig:IAppConfigurtaion,
+                private sdcMenu:IAppMenu,
+                private ComponentFactory:ComponentFactory,
+                private $filter:ng.IFilterService,
+                private ModalsHandler:ModalsHandler,
+                private ServiceServiceNg2:ServiceServiceNg2) {
+
+    }
+
+    private actualChangeLifecycleState = (component:Component, data:any, scope:any, onSuccessCallback?:Function, onErrorCallback?:Function):void => {
+
+        let self = this;
+
+        let getContacts = (component:Component):string => {
+            let testers = this.sdcConfig.testers;
+            let result:string = testers[component.componentType][component.categories[0].name] ?
+                testers[component.componentType][component.categories[0].name] :
+                testers[component.componentType]['default'];
+            return result;
+        };
+
+        let onSuccess = (newComponent:Component):void => {
+            //scope.isLoading = false;
+            console.info(component.componentType.toLowerCase + ' change state ', newComponent);
+            if (onSuccessCallback) {
+                onSuccessCallback(self.ComponentFactory.createComponent(newComponent), data.url);
+            }
+        };
+
+        let onError = (error):void => {
+            scope.isLoading = false;
+            console.info('Failed to changeLifecycleState to ', data.url);
+            if (onErrorCallback) {
+                onErrorCallback(error);
+            }
+        };
+
+        let comment:AsdcComment = new AsdcComment();
+        if (data.alertModal) {
+            // Show alert dialog if defined in menu.json
+            //-------------------------------------------------
+            let onOk = (confirmationText):void => {
+                comment.userRemarks = confirmationText;
+                scope.isLoading = true;
+                component.changeLifecycleState(data.url, comment).then(onSuccess, onError);
+            };
+
+            let onCancel = ():void => {
+                console.info('Cancel pressed');
+                scope.isLoading = false;
+            };
+
+            let modalTitle = this.sdcMenu.alertMessages[data.alertModal].title;
+            let modalMessage = this.sdcMenu.alertMessages[data.alertModal].message.format([component.componentType.toLowerCase()]);
+            this.ModalsHandler.openAlertModal(modalTitle, modalMessage).then(onOk, onCancel);
+        } else if (data.confirmationModal) {
+            // Show confirmation dialog if defined in menu.json
+            //-------------------------------------------------
+            let onOk = (confirmationText):void => {
+                comment.userRemarks = confirmationText;
+                scope.isLoading = true;
+                component.changeLifecycleState(data.url, comment).then(onSuccess, onError);
+            };
+
+            let onCancel = ():void => {
+                console.info('Cancel pressed');
+                scope.isLoading = false;
+            };
+
+            let modalTitle = this.sdcMenu.confirmationMessages[data.confirmationModal].title;
+            let modalMessage = this.sdcMenu.confirmationMessages[data.confirmationModal].message.format([component.componentType.toLowerCase()]);
+            let modalShowComment = this.sdcMenu.confirmationMessages[data.confirmationModal].showComment;
+            this.ModalsHandler.openConfirmationModal(modalTitle, modalMessage, modalShowComment).then(onOk, onCancel);
+
+        } else if (data.emailModal) {
+            // Show email dialog if defined in menu.json
+            //-------------------------------------------------
+            let onOk = (resource):void => {
+                if (resource) {
+                    onSuccess(resource);
+                } else {
+                    onError("Error changing life cycle state");
+                }
+            };
+
+            let onCancel = ():void => {
+                scope.isLoading = false;
+            };
+
+            let emailModel:IEmailModalModel = <IEmailModalModel>{};
+            emailModel.email = <IEmailModalModel_Email>{};
+            emailModel.data = <IEmailModalModel_Data>{};
+            emailModel.title = this.$filter('translate')("EMAIL_MODAL_TITLE");
+            emailModel.email.to = getContacts(component);
+            emailModel.email.subject = this.$filter('translate')("EMAIL_MODAL_SUBJECT", "{'entityName': '" + this.$filter('resourceName')(component.name) + "','entityVersion': '" + component.version + "'}");
+            emailModel.email.message = '';
+            emailModel.data.component = component;
+            emailModel.data.stateUrl = data.url;
+
+            this.ModalsHandler.openEmailModal(emailModel).then(onOk, onCancel);
+
+        } else {
+            // Submit to server only (no modal is shown).
+            scope.isLoading = true;
+            component.changeLifecycleState(data.url, comment).then(onSuccess, onError);
+        }
+
+    }
+
+    public changeLifecycleState = (component:Component, data:any, scope:any, onSuccessCallback?:Function, onErrorCallback?:Function):void => {
+
+        if (data.conformanceLevelModal) {
+            this.validateConformanceLevel(component, data, scope, onSuccessCallback, onErrorCallback);
+        } else {
+            this.actualChangeLifecycleState(component, data, scope, onSuccessCallback, onErrorCallback);
+        }
+    }
+
+    private validateConformanceLevel = (component:Component, data:any, scope:any, onSuccessCallback?:Function, onErrorCallback?:Function):void => {
+        // Validate conformance level if defined in menu.json
+        //-------------------------------------------------
+        this.ServiceServiceNg2.validateConformanceLevel(<Service>component).subscribe((res:boolean) => {
+            if (res === true) {
+                //conformance level is ok - continue
+                this.actualChangeLifecycleState(component, data, scope, onSuccessCallback, onErrorCallback);
+
+            } else {
+                //show warning modal
+                this.ModalsHandler.openConformanceLevelModal()
+                    .then(() => {
+                        //continue distribute
+                        this.actualChangeLifecycleState(component, data, scope, onSuccessCallback, onErrorCallback);
+
+                    }).catch(() => {
+                        //reject distribution
+                        this.actualChangeLifecycleState(component, data.conformanceLevelModal, scope, onSuccessCallback, onErrorCallback);
+                });
+            }
+        });
+    }
+}
diff --git a/catalog-ui/src/app/utils/common-utils.ts b/catalog-ui/src/app/utils/common-utils.ts
new file mode 100644
index 0000000..d8019d2
--- /dev/null
+++ b/catalog-ui/src/app/utils/common-utils.ts
@@ -0,0 +1,96 @@
+import {Module, AttributeModel, ResourceInstance, PropertyModel, InputFEModel} from "../models";
+import {ComponentInstanceFactory} from "./component-instance-factory";
+import {PropertyBEModel, RelationshipModel} from "app/models";
+
+export class CommonUtils {
+
+    static initProperties(propertiesObj:Array<PropertyModel>, uniqueId?:string):Array<PropertyModel> {
+
+        let properties = new Array<PropertyModel>();
+        if (propertiesObj) {
+            _.forEach(propertiesObj, (property:PropertyModel):void => {
+                if (uniqueId) {
+                    property.readonly = property.parentUniqueId != uniqueId;
+                }
+                properties.push(new PropertyModel(property));
+            });
+        }
+        return properties;
+    };
+
+    static initAttributes(attributesObj:Array<AttributeModel>, uniqueId?:string):Array<AttributeModel> {
+
+        let attributes = new Array<AttributeModel>();
+        if (attributesObj) {
+            _.forEach(attributesObj, (attribute:AttributeModel):void => {
+                if (uniqueId) {
+                    attribute.readonly = attribute.parentUniqueId != uniqueId;
+                }
+                attributes.push(new AttributeModel(attribute));
+            });
+        }
+        return attributes;
+    };
+
+    static initComponentInstances(componentInstanceObj:Array<ResourceInstance>):Array<ResourceInstance> {
+
+        let componentInstances = new Array<ResourceInstance>();
+        if (componentInstanceObj) {
+            _.forEach(componentInstanceObj, (instance:ResourceInstance):void => {
+                componentInstances.push(ComponentInstanceFactory.createComponentInstance(instance));
+            });
+        }
+        return componentInstances;
+    };
+
+    static initModules(moduleArrayObj:Array<Module>):Array<Module> {
+
+        let modules = new Array<Module>();
+
+        if (moduleArrayObj) {
+            _.forEach(moduleArrayObj, (module:Module):void => {
+                if (module.type === "org.openecomp.groups.VfModule") {
+                    modules.push(new Module(module));
+                }
+            });
+        }
+        return modules;
+    };
+
+    static initInputs(inputsObj:Array<PropertyBEModel>):Array<PropertyBEModel> {
+
+        let inputs = new Array<PropertyBEModel>();
+
+        if(inputsObj) {
+            _.forEach(inputsObj, (input:PropertyBEModel):void => {
+                inputs.push(new PropertyBEModel(input));
+            })
+        }
+
+        return inputs;
+    }
+
+    static initBeProperties(propertiesObj: Array<PropertyBEModel>): Array<PropertyBEModel> {
+
+        let properties = new Array<PropertyBEModel>();
+
+        if (propertiesObj) {
+            _.forEach(propertiesObj, (property: PropertyBEModel): void => {
+                properties.push(new PropertyBEModel(property));
+            })
+        }
+
+        return properties;
+    }
+
+    static initComponentInstanceRelations = (componentInstanceRelationsObj:Array<RelationshipModel>):Array<RelationshipModel> => {
+        if (componentInstanceRelationsObj) {
+             let componentInstancesRelations: Array<RelationshipModel> = [];
+            _.forEach(componentInstanceRelationsObj, (instanceRelation:RelationshipModel):void => {
+                componentInstancesRelations.push(new RelationshipModel(instanceRelation));
+            });
+            return componentInstancesRelations;
+        }
+    };
+}
+
diff --git a/catalog-ui/src/app/utils/component-factory.ts b/catalog-ui/src/app/utils/component-factory.ts
new file mode 100644
index 0000000..18edbfb
--- /dev/null
+++ b/catalog-ui/src/app/utils/component-factory.ts
@@ -0,0 +1,161 @@
+'use strict';
+import {DEFAULT_ICON, ResourceType, ComponentType} from "./constants";
+import {ServiceService, CacheService, ResourceService, ProductService} from "app/services";
+import {IMainCategory, ISubCategory, ICsarComponent, Component, Resource, Service, Product} from "app/models";
+import {ComponentMetadata} from "../models/component-metadata";
+import {ComponentServiceNg2} from "../ng2/services/component-services/component.service";
+import {ComponentGenericResponse} from "../ng2/services/responses/component-generic-response";
+
+
+export class ComponentFactory {
+
+    static '$inject' = [
+        'Sdc.Services.Components.ResourceService',
+        'Sdc.Services.Components.ServiceService',
+        'Sdc.Services.Components.ProductService',
+        'Sdc.Services.CacheService',
+        '$q',
+        'ComponentServiceNg2'
+    ];
+
+    constructor(private ResourceService:ResourceService,
+                private ServiceService:ServiceService,
+                private ProductService:ProductService,
+                private cacheService:CacheService,
+                private $q:ng.IQService,
+                private ComponentServiceNg2: ComponentServiceNg2) {
+    }
+
+    public createComponent = (component:Component):Component => {
+        let newComponent:Component;
+        switch (component.componentType) {
+
+            case 'SERVICE':
+                newComponent = new Service(this.ServiceService, this.$q, <Service> component);
+                break;
+
+            case 'RESOURCE':
+                newComponent = new Resource(this.ResourceService, this.$q, <Resource> component);
+                break;
+
+            case 'PRODUCT':
+                newComponent = new Product(this.ProductService, this.$q, <Product> component);
+                break;
+        }
+        return newComponent;
+    };
+
+    public createProduct = (product:Product):Product => {
+        let newProduct:Product = new Product(this.ProductService, this.$q, <Product> product);
+        return newProduct;
+    };
+
+    public createService = (service:Service):Service => {
+        let newService:Service = new Service(this.ServiceService, this.$q, <Service> service);
+        return newService;
+    };
+
+    public createResource = (resource:Resource):Resource => {
+        let newResource:Resource = new Resource(this.ResourceService, this.$q, <Resource> resource);
+        return newResource;
+    };
+
+    public createFromCsarComponent = (csar:ICsarComponent):Component => {
+        let newResource:Resource = <Resource>this.createEmptyComponent(ComponentType.RESOURCE);
+        newResource.name = csar.vspName;
+
+        /**
+         * Onboarding CSAR contains category and sub category that are uniqueId.
+         * Need to find the category and sub category and extract the name from them.
+         * First concat all sub categories to one array.
+         * Then find the selected sub category and category.
+         * @type {any}
+         */
+        let availableCategories = angular.copy(this.cacheService.get('resourceCategories'));
+        let allSubs = [];
+        _.each(availableCategories, (main:IMainCategory)=> {
+            if (main.subcategories) {
+                allSubs = allSubs.concat(main.subcategories);
+            }
+        });
+
+        let selectedCategory:IMainCategory = _.find(availableCategories, function (main:IMainCategory) {
+            return main.uniqueId === csar.category;
+        });
+
+        let selectedSubCategory:ISubCategory = _.find(allSubs, (sub:ISubCategory)=> {
+            return sub.uniqueId === csar.subCategory;
+        });
+
+        // Build the categories and sub categories array (same format as component category)
+        let categories:Array<IMainCategory> = new Array();
+        let subcategories:Array<ISubCategory> = new Array();
+        if (selectedCategory && selectedSubCategory) {
+            subcategories.push(selectedSubCategory);
+            selectedCategory.subcategories = subcategories;
+            categories.push(selectedCategory);
+        }
+
+        // Fill the component with details from CSAR
+        newResource.selectedCategory = selectedCategory && selectedSubCategory ? selectedCategory.name + "_#_" + selectedSubCategory.name : '';
+        newResource.categories = categories;
+        newResource.vendorName = csar.vendorName;
+        newResource.vendorRelease = csar.vendorRelease;
+        newResource.csarUUID = csar.packageId;
+        newResource.csarPackageType = csar.packageType;
+        newResource.csarVersion = csar.version;
+        newResource.packageId = csar.packageId;
+        newResource.description = csar.description;
+        return newResource;
+    };
+
+    public createEmptyComponent = (componentType:string):Component => {
+        let newComponent:Component;
+
+        switch (componentType) {
+
+            case ComponentType.SERVICE:
+                newComponent = new Service(this.ServiceService, this.$q);
+                break;
+
+            case ComponentType.RESOURCE:
+            case ResourceType.VF:
+            case ResourceType.VL:
+            case ResourceType.VFC:
+            case ResourceType.CP:
+                newComponent = new Resource(this.ResourceService, this.$q);
+                break;
+
+            case ComponentType.PRODUCT:
+                newComponent = new Product(this.ProductService, this.$q);
+                break;
+        }
+        newComponent.componentType = componentType;
+        newComponent.tags = [];
+        newComponent.icon = DEFAULT_ICON;
+        return newComponent;
+    };
+
+    public getComponentFromServer = (componentType:string, componentId:string):ng.IPromise<Component> => {
+        let newComponent:Component = this.createEmptyComponent(componentType);
+        newComponent.setUniqueId(componentId);
+        return newComponent.getComponent();
+    };
+
+    public createComponentOnServer = (componentObject:Component):ng.IPromise<Component> => {
+        let component:Component = this.createComponent(componentObject);
+        return component.createComponentOnServer();
+
+    };
+
+    public getComponentWithMetadataFromServer = (componentType:string, componentId:string):ng.IPromise<Component> => {
+        let deferred = this.$q.defer();
+        let component = this.createEmptyComponent(componentType);
+        component.setUniqueId(componentId);
+        this.ComponentServiceNg2.getComponentMetadata(component).subscribe((response:ComponentGenericResponse) => {
+            component.setComponentMetadata(response.metadata);
+            deferred.resolve(component);
+        });
+        return deferred.promise;
+    }
+}
diff --git a/catalog-ui/src/app/utils/component-instance-factory.ts b/catalog-ui/src/app/utils/component-instance-factory.ts
new file mode 100644
index 0000000..df92f20
--- /dev/null
+++ b/catalog-ui/src/app/utils/component-instance-factory.ts
@@ -0,0 +1,81 @@
+/*-
+ * ============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=========================================================
+ */
+/**
+ * Created by obarda on 3/7/2016.
+ */
+'use strict';
+import {ComponentInstance, ServiceInstance, ProductInstance, ResourceInstance, Component} from "../models";
+import {LeftPaletteComponent} from "../models/components/displayComponent";
+
+export class ComponentInstanceFactory {
+
+    static createComponentInstance(componentInstance:ComponentInstance):ComponentInstance {
+        let newComponentInstance:ComponentInstance;
+        switch (componentInstance.originType) {
+            case 'SERVICE':
+                newComponentInstance = new ServiceInstance(componentInstance);
+                break;
+
+            case 'PRODUCT':
+                newComponentInstance = new ProductInstance(componentInstance);
+                break;
+
+            default :
+                newComponentInstance = new ResourceInstance(componentInstance);
+                break;
+        }
+        return newComponentInstance;
+    };
+
+    public createEmptyComponentInstance = (componentInstanceType?:string):ComponentInstance => {
+        let newComponentInstance:ComponentInstance;
+        switch (componentInstanceType) {
+            case 'SERVICE':
+                newComponentInstance = new ServiceInstance();
+                break;
+
+            case 'PRODUCT':
+                newComponentInstance = new ProductInstance();
+                break;
+
+            default :
+                newComponentInstance = new ResourceInstance();
+                break;
+        }
+        return newComponentInstance;
+    };
+
+    public createComponentInstanceFromComponent = (component:LeftPaletteComponent):ComponentInstance => {
+        let newComponentInstance:ComponentInstance = this.createEmptyComponentInstance(component.componentType);
+        newComponentInstance.uniqueId = component.uniqueId + (new Date()).getTime();
+        newComponentInstance.posX = 0;
+        newComponentInstance.posY = 0;
+        newComponentInstance.name = component.name;
+        newComponentInstance.componentVersion = component.version;
+        newComponentInstance.originType = component.getComponentSubType();
+        //new component instance -> req. & cap. are added on successful instance creation
+        newComponentInstance.requirements = component.requirements;
+        newComponentInstance.capabilities = component.capabilities;
+        newComponentInstance.icon = component.icon;
+        newComponentInstance.componentUid = component.uniqueId;
+        return newComponentInstance;
+    };
+
+}
diff --git a/catalog-ui/src/app/utils/constants.ts b/catalog-ui/src/app/utils/constants.ts
new file mode 100644
index 0000000..d55079d
--- /dev/null
+++ b/catalog-ui/src/app/utils/constants.ts
@@ -0,0 +1,277 @@
+/**
+ * Created by obarda on 2/18/2016.
+ */
+
+export let DEFAULT_ICON = 'defaulticon';
+export let CP_END_POINT = 'CpEndPoint';
+export let CHANGE_COMPONENT_CSAR_VERSION_FLAG = 'changeComponentCsarVersion';
+
+export class ComponentType {
+    static SERVICE = 'SERVICE';
+    static RESOURCE = 'RESOURCE';
+    static PRODUCT = 'PRODUCT';
+}
+
+export class ServerTypeUrl {
+    static RESOURCES = 'resources/';
+    static SERVICES = 'services/';
+    static PRODUCTS = 'product/';
+}
+
+export class ResourceType {
+    static VF = 'VF';
+    static VL = 'VL';
+    static CP = 'CP';
+    static VFC = 'VFC';
+    static VFCMT = 'VFCMT';
+}
+
+export class ComponentState {
+    static CERTIFICATION_IN_PROGRESS = 'CERTIFICATION_IN_PROGRESS';
+    static CERTIFIED = 'CERTIFIED';
+    static NOT_CERTIFIED_CHECKOUT = 'NOT_CERTIFIED_CHECKOUT';
+    static NOT_CERTIFIED_CHECKIN = 'NOT_CERTIFIED_CHECKIN';
+    static READY_FOR_CERTIFICATION = 'READY_FOR_CERTIFICATION';
+}
+
+export class DistributionStatus {
+    DISTRIBUTION_NOT_APPROVED = 'DISTRIBUTION_NOT_APPROVED';
+    DISTRIBUTION_APPROVED = 'DISTRIBUTION_APPROVED';
+    DISTRIBUTED = 'DISTRIBUTED';
+    DISTRIBUTION_REJECTED = 'DISTRIBUTION_REJECTED';
+}
+
+export class ArtifactGroupType {
+    static DEPLOYMENT = "DEPLOYMENT";
+    static INFORMATION = "INFORMATIONAL";
+    static SERVICE_API = "SERVICE_API";
+}
+
+export class ArtifactType {
+    static HEAT = "HEAT";
+    static HEAT_VOL = "HEAT_VOL";
+    static HEAT_NET = "HEAT_NET";
+    static VF_LICENSE = "VF_LICENSE";
+    static VENDOR_LICENSE = "VENDOR_LICENSE";
+    static THIRD_PARTY_RESERVED_TYPES = {
+        WORKFLOW: "WORKFLOW",
+        NETWORK_CALL_FLOW: "NETWORK_CALL_FLOW",
+        AAI_SERVICE_MODEL: "AAI_SERVICE_MODEL",
+        AAI_VF_MODEL: "AAI_VF_MODEL",
+        AAI_VF_MODULE_MODEL: "AAI_VF_MODULE_MODEL",
+        AAI_VF_INSTANCE_MODEL: "AAI_VF_INSTANCE_MODEL"
+    };
+    static TOSCA = {TOSCA_TEMPLATE: "TOSCA_TEMPLATE", TOSCA_CSAR: "TOSCA_CSAR"};
+}
+
+export class SEVERITY {
+    public static DEBUG = 'DEBUG';
+    public static INFO = 'INFO';
+    public static WARNING = 'WARNING';
+    public static ERROR = 'ERROR';
+}
+
+export class PROPERTY_TYPES {
+    public static STRING = 'string';
+    public static INTEGER = 'integer';
+    public static FLOAT = 'float';
+    public static BOOLEAN = 'boolean';
+    public static JSON = 'json';
+    public static MAP = 'map';
+    public static LIST = 'list';
+}
+
+export class SOURCES {
+    public static A_AND_AI = 'A&AI';
+    public static ORDER = 'Order';
+    public static RUNTIME = 'Runtime';
+}
+
+export class PROPERTY_DATA {
+    public static TYPES = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.FLOAT, PROPERTY_TYPES.BOOLEAN, PROPERTY_TYPES.JSON, PROPERTY_TYPES.LIST, PROPERTY_TYPES.MAP];
+    public static SIMPLE_TYPES = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.FLOAT, PROPERTY_TYPES.BOOLEAN, PROPERTY_TYPES.JSON];
+    public static ROOT_DATA_TYPE = "tosca.datatypes.Root";
+    public static SOURCES = [SOURCES.A_AND_AI, SOURCES.ORDER, SOURCES.RUNTIME];
+}
+
+export class PROPERTY_VALUE_CONSTRAINTS {
+    public static MAX_LENGTH = 100;
+    public static JSON_MAX_LENGTH = 4096;
+}
+
+export class Role {
+    public static ADMIN = 'ADMIN';
+    public static DESIGNER = 'DESIGNER';
+    public static PRODUCT_STRATEGIST = 'PRODUCT_STRATEGIST';
+    public static PRODUCT_MANAGER = 'PRODUCT_MANAGER';
+    public static TESTER = 'TESTER';
+    public static OPS = 'OPS';
+    public static GOVERNOR = 'GOVERNOR';
+}
+
+export enum FormState{
+    CREATE,
+    UPDATE,
+    IMPORT,
+    VIEW
+}
+
+export class WorkspaceMode {
+    public static CREATE = 'create';
+    public static EDIT = 'edit';
+    public static IMPORT = 'import';
+    public static VIEW = 'view';
+}
+
+export class ImagesUrl {
+    public static RESOURCE_ICONS = '/assets/styles/images/resource-icons/';
+    public static SERVICE_ICONS = '/assets/styles/images/service-icons/';
+    public static SELECTED_UCPE_INSTANCE = '/assets/styles/images/resource-icons/selectedUcpeInstance.png';
+    public static SELECTED_CP_INSTANCE = '/assets/styles/images/resource-icons/selectedCPInstance.png';
+    public static SELECTED_VL_INSTANCE = '/assets/styles/images/resource-icons/selectedVLInstance.png';
+    public static CANVAS_PLUS_ICON = '/assets/styles/images/resource-icons/canvasPlusIcon.png';
+    public static MODULE_ICON = '/assets/styles/images/resource-icons/module.png';
+    public static OPEN_MODULE_ICON = '/assets/styles/images/resource-icons/openModule.png';
+    public static OPEN_MODULE_HOVER_ICON = '/assets/styles/images/resource-icons/openModuleHover.png';
+    public static CLOSE_MODULE_ICON = '/assets/styles/images/resource-icons/closeModule.png';
+    public static CLOSE_MODULE_HOVER_ICON = '/assets/styles/images/resource-icons/closeModuleHover.png';
+}
+
+export class ModalType {
+    static STANDARD = 'standard';
+    static ERROR = 'error';
+    static ALERT = 'alert';
+}
+
+export class GraphColors {
+    public static NOT_CERTIFIED_LINK = 'rgb(218,31,61)';
+    public static VL_LINK = 'rgb(216,216,216)';
+    public static ACTIVE_LINK = '#30bdf2';
+    public static BASE_LINK = 'rgb(55,55,55)';
+    public static NODE_BACKGROUND_COLOR = 'rgba(46, 162, 157, 0.24)';
+    public static NODE_SHADOW_COLOR = 'rgba(198, 230, 228, 0.7)';
+    public static NODE_OVERLAPPING_BACKGROUND_COLOR = 'rgba(179, 10, 60, 0.24)';
+    public static NODE_OVERLAPPING_SHADOW_COLOR = 'rgba(236, 194, 206, 0.7)';
+    public static NODE_UCPE_CP = '#9063cd';
+    public static NODE_UCPE = '#fbfbfb';
+    public static NODE_SELECTED_BORDER_COLOR = '#30bdf2';
+}
+export class GraphTransactionLogText {
+    public static REMOVE_TEMP_LINK = "remove tempLink";
+    public static DELETE_LINK = "delete link";
+    public static ADD_LINK = "delete link";
+    public static ADD_NODE = "adding node";
+}
+
+export class GraphUIObjects {
+    public static LINK_MENU_HEIGHT = 420;
+    public static TOP_HEADER_HEIGHT = 200;
+    public static TOOLTIP_OFFSET_X = 50;
+    public static TOOLTIP_OFFSET_Y = 145;
+    public static TOOLTIP_LINK_OFFSET_X = 35;
+    public static TOOLTIP_LINK_OFFSET_Y = 75;
+    public static MENU_LINK_VL_HEIGHT_OFFSET = 250;
+    public static MENU_LINK_VL_WIDTH_OFFSET = 200;
+    public static MENU_LINK_SIMPLE_HEIGHT_OFFSET = 180;
+    public static MENU_LINK_SIMPLE_WIDTH_OFFSET = 130;
+    public static DIAGRAM_RIGHT_WIDTH_OFFSET = 248;
+    public static DIAGRAM_HEADER_OFFSET = 103;
+    public static DIAGRAM_PALETTE_WIDTH_OFFSET = 247;
+    // public static COMPOSITION_HEADER_OFFSET = 50;
+    // public static COMPOSITION_NODE_MENU_WIDTH = 230;
+    // public static COMPOSITION_NODE_MENU_HEIGHT = 200;
+    // public static COMPOSITION_RIGHT_PANEL_OFFSET = 300;
+}
+
+
+export class States {
+    public static WORKSPACE_GENERAL = 'workspace.general';
+    public static WORKSPACE_ICONS = 'workspace.icons';
+    public static WORKSPACE_ACTIVITY_LOG = 'workspace.activity_log';
+    public static WORKSPACE_DEPLOYMENT_ARTIFACTS = 'workspace.deployment_artifacts';
+    public static WORKSPACE_PROPERTIES = 'workspace.properties';
+    public static WORKSPACE_SERVICE_INPUTS = 'workspace.service_inputs';
+    public static WORKSPACE_RESOURCE_INPUTS = 'workspace.resource_inputs';
+    public static WORKSPACE_ATTRIBUTES = 'workspace.attributes';
+    public static WORKSPACE_HIERARCHY = 'workspace.hierarchy';
+    public static WORKSPACE_INFORMATION_ARTIFACTS = 'workspace.information_artifacts';
+    public static WORKSPACE_TOSCA_ARTIFACTS = 'workspace.tosca_artifacts';
+    public static WORKSPACE_COMPOSITION = 'workspace.composition';
+    public static WORKSPACE_NETWORK_CALL_FLOW = 'workspace.network_call_flow';
+    public static WORKSPACE_MANAGEMENT_WORKFLOW = 'workspace.management_workflow';
+    public static WORKSPACE_DEPLOYMENT = 'workspace.deployment';
+    public static WORKSPACE_DISTRIBUTION = 'workspace.distribution';
+    public static WORKSPACE_PROPERTIES_ASSIGNMENT = 'workspace.properties_assignment';
+    public static WORKSPACE_REQUIREMENTS_AND_CAPABILITIES = 'workspace.reqAndCap';
+    public static WORKSPACE_NG2 = 'workspace.ng2';
+}
+
+export class EVENTS {
+    static RESOURCE_LEFT_PALETTE_UPDATE_EVENT = "resourceLeftPanelUpdateEvent";
+    static SERVICE_LEFT_PALETTE_UPDATE_EVENT = "serviceLeftPanelUpdateEvent";
+    static PRODUCT_LEFT_PALETTE_UPDATE_EVENT = "productLeftPanelUdateEvent";
+    static VL_LEFT_PALETTE_UPDATE_EVENT = "vlLeftPanelUdateEvent";
+    static ON_CSAR_LOADING = "onCsarLoading";
+    static DOWNLOAD_ARTIFACT_FINISH_EVENT = "downloadArtifactFinishEvent";
+    static ON_WORKSPACE_SAVE_BUTTON_CLICK = "onWorkspaceSaveButtonClick";
+    static ON_WORKSPACE_SAVE_BUTTON_SUCCESS = "onWorkspaceSaveButtonSuccess";
+    static ON_WORKSPACE_SAVE_BUTTON_ERROR = "onWorkspaceSaveButtonError";
+
+    //Loader events
+    static SHOW_LOADER_EVENT = "showLoaderEvent";
+    static HIDE_LOADER_EVENT = "hideLoaderEvent";
+}
+
+
+export class UNIQUE_GROUP_PROPERTIES_NAME {
+    public static MIN_VF_MODULE_INSTANCES = 'min_vf_module_instances';
+    public static MAX_VF_MODULE_INSTANCES = 'max_vf_module_instances';
+    public static INITIAL_COUNT = 'initial_count';
+    public static IS_BASE = 'isBase';
+    public static VF_MODULE_TYPE = 'vf_module_type';
+    public static VF_MODULE_LABEL = 'vf_module_label';
+    public static VF_MODULE_DESCRIPTION = 'vf_module_description';
+    public static VOLUME_GROUP = 'volume_group';
+}
+
+
+export class GRAPH_EVENTS {
+    static ON_COMPOSITION_GRAPH_DATA_LOADED = 'onCompositionGraphDataLoaded';
+    static ON_DEPLOYMENT_GRAPH_DATA_LOADED = 'onDeploymentGraphDataLoaded';
+    static ON_NODE_SELECTED = "onNodeSelected";
+    static ON_GRAPH_BACKGROUND_CLICKED = "onGraphBackgroundClicked";
+    static ON_PALETTE_COMPONENT_HOVER_IN = 'onPaletteComponentHoverIn';
+    static ON_PALETTE_COMPONENT_HOVER_OUT = 'onPaletteComponentHoverOut';
+    static ON_PALETTE_COMPONENT_DRAG_START = 'onPaletteComponentDragStart';
+    static ON_PALETTE_COMPONENT_DRAG_ACTION = 'onPaletteComponentDragAction';
+    static ON_COMPONENT_INSTANCE_NAME_CHANGED = 'onComponentInstanceNameChanged';
+    static ON_DELETE_COMPONENT_INSTANCE = 'onDeleteComponentInstance';
+    static ON_DELETE_MULTIPLE_COMPONENTS = 'onDeleteMultipleComponents';
+    static ON_DELETE_EDGE = 'onDeleteEdge';
+    static ON_INSERT_NODE_TO_UCPE = 'onInsertNodeToUCPE';
+    static ON_REMOVE_NODE_FROM_UCPE = 'onRemoveNodeFromUCPE';
+    static ON_VERSION_CHANGED = 'onVersionChanged';
+    static ON_CREATE_COMPONENT_INSTANCE = 'onCreateComponentInstance';
+}
+
+
+export class COMPONENT_FIELDS {
+    static COMPONENT_INSTANCES_PROPERTIES = "componentInstancesProperties";
+    static COMPONENT_INSTANCES_ATTRIBUTES = "componentInstancesAttributes";
+    static COMPONENT_ATTRIBUTES = "attributes";
+    static COMPONENT_INSTANCES = "componentInstances";
+    static COMPONENT_INSTANCES_RELATION = "componentInstancesRelations";
+    static COMPONENT_INPUTS = "inputs";
+    static COMPONENT_METADATA = "metadata";
+    static COMPONENT_DEPLOYMENT_ARTIFACTS = "deploymentArtifacts";
+    static COMPONENT_INFORMATIONAL_ARTIFACTS = "artifacts";
+    static COMPONENT_PROPERTIES = "properties";
+    static COMPONENT_CAPABILITIES = "capabilities";
+    static COMPONENT_REQUIREMENTS = "requirements";
+    static COMPONENT_TOSCA_ARTIFACTS = "toscaArtifacts";
+    static COMPONENT_GROUPS = "groups";
+
+}
+export class API_QUERY_PARAMS {
+    static INCLUDE = "include";
+}
diff --git a/catalog-ui/src/app/utils/dictionary/dictionary.ts b/catalog-ui/src/app/utils/dictionary/dictionary.ts
new file mode 100644
index 0000000..fd2a028
--- /dev/null
+++ b/catalog-ui/src/app/utils/dictionary/dictionary.ts
@@ -0,0 +1,235 @@
+/**
+
+ This code was copy from collections.ts lib
+ https://github.com/basarat/typescript-collections
+ **/
+'use strict';
+
+// Used internally by dictionary
+interface IDictionaryPair<K, V> {
+    key:K;
+    value:V;
+}
+
+export class Dictionary<K, V> {
+
+    /**
+     * Object holding the key-value pairs.
+     * @type {Object}
+     * @private
+     */
+    private table:{ [key:string]:IDictionaryPair<K, V> };
+    //: [key: K] will not work since indices can only by strings in javascript and typescript enforces this.
+
+    /**
+     * Number of elements in the list.
+     * @type {number}
+     * @private
+     */
+    private nElements:number;
+
+    /**
+     * Function used to convert keys to strings.
+     * @type {function(Object):string}
+     * @private
+     */
+    private toStr:(key:K) => string;
+
+
+    /**
+     * Creates an empty dictionary.
+     * @class <p>Dictionaries map keys to values; each key can map to at most one value.
+     * This implementation accepts any kind of objects as keys.</p>
+     *
+     * <p>If the keys are custom objects a function which converts keys to unique
+     * strings must be provided. Example:</p>
+     * <pre>
+     * function petToString(pet) {
+       *  return pet.name;
+       * }
+     * </pre>
+     * @constructor
+     * @param {function(Object):string=} toStrFunction optional function used
+     * to convert keys to strings. If the keys aren"t strings or if toString()
+     * is not appropriate, a custom function which receives a key and returns a
+     * unique string must be provided.
+     */
+    constructor(toStrFunction?:(key:K) => string) {
+        this.table = {};
+        this.nElements = 0;
+        this.toStr = toStrFunction || this.defaultToString;
+    }
+
+
+    /**
+     copy from angular.js  isUndefined
+     */
+    private isUndefined = (value:any):boolean => {
+        return typeof value === 'undefined';
+    }
+
+    defaultToString = (item:any):string => {
+        return item.toString();
+    }
+
+    /**
+     * Returns the value to which this dictionary maps the specified key.
+     * Returns undefined if this dictionary contains no mapping for this key.
+     * @param {Object} key key whose associated value is to be returned.
+     * @return {*} the value to which this dictionary maps the specified key or
+     * undefined if the map contains no mapping for this key.
+     */
+    getValue = (key:K):V => {
+        let pair:IDictionaryPair<K, V> = this.table[this.toStr(key)];
+        if (this.isUndefined(pair)) {
+            return undefined;
+        }
+        return pair.value;
+    }
+
+
+    /**
+     * Associates the specified value with the specified key in this dictionary.
+     * If the dictionary previously contained a mapping for this key, the old
+     * value is replaced by the specified value.
+     * @param {Object} key key with which the specified value is to be
+     * associated.
+     * @param {Object} value value to be associated with the specified key.
+     * @return {*} previous value associated with the specified key, or undefined if
+     * there was no mapping for the key or if the key/value are undefined.
+     */
+    setValue = (key:K, value:V):V => {
+
+        if (this.isUndefined(key) || this.isUndefined(value)) {
+            return undefined;
+        }
+
+        let ret:V;
+        let k = this.toStr(key);
+        let previousElement:IDictionaryPair<K, V> = this.table[k];
+        if (this.isUndefined(previousElement)) {
+            this.nElements++;
+            ret = undefined;
+        } else {
+            ret = previousElement.value;
+        }
+        this.table[k] = {
+            key: key,
+            value: value
+        };
+        return ret;
+    }
+
+    /**
+     * Removes the mapping for this key from this dictionary if it is present.
+     * @param {Object} key key whose mapping is to be removed from the
+     * dictionary.
+     * @return {*} previous value associated with specified key, or undefined if
+     * there was no mapping for key.
+     */
+    remove = (key:K):V => {
+        let k = this.toStr(key);
+        let previousElement:IDictionaryPair<K, V> = this.table[k];
+        if (!this.isUndefined(previousElement)) {
+            delete this.table[k];
+            this.nElements--;
+            return previousElement.value;
+        }
+        return undefined;
+    }
+
+    /**
+     * Returns an array containing all of the keys in this dictionary.
+     * @return {Array} an array containing all of the keys in this dictionary.
+     */
+    keys = ():K[] => {
+        let array:K[] = [];
+        for (let name in this.table) {
+            if (this.table.hasOwnProperty(name)) {
+                let pair:IDictionaryPair<K, V> = this.table[name];
+                array.push(pair.key);
+            }
+        }
+        return array;
+    }
+
+    /**
+     * Returns an array containing all of the values in this dictionary.
+     * @return {Array} an array containing all of the values in this dictionary.
+     */
+    values = ():V[] => {
+        let array:V[] = [];
+        for (let name in this.table) {
+            if (this.table.hasOwnProperty(name)) {
+                let pair:IDictionaryPair<K, V> = this.table[name];
+                array.push(pair.value);
+            }
+        }
+        return array;
+    }
+
+    /**
+     * Executes the provided function once for each key-value pair
+     * present in this dictionary.
+     * @param {function(Object,Object):*} callback function to execute, it is
+     * invoked with two arguments: key and value. To break the iteration you can
+     * optionally return false.
+     */
+    forEach = (callback:(key:K, value:V) => any):void => {
+        for (let name in this.table) {
+            if (this.table.hasOwnProperty(name)) {
+                let pair:IDictionaryPair<K, V> = this.table[name];
+                let ret = callback(pair.key, pair.value);
+                if (ret === false) {
+                    return;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns true if this dictionary contains a mapping for the specified key.
+     * @param {Object} key key whose presence in this dictionary is to be
+     * tested.
+     * @return {boolean} true if this dictionary contains a mapping for the
+     * specified key.
+     */
+    containsKey = (key:K):boolean => {
+        return !this.isUndefined(this.getValue(key));
+    }
+
+    /**
+     * Removes all mappings from this dictionary.
+     * @this {Dictionary}
+     */
+    clear = () => {
+
+        this.table = {};
+        this.nElements = 0;
+    }
+
+    /**
+     * Returns the number of keys in this dictionary.
+     * @return {number} the number of key-value mappings in this dictionary.
+     */
+    size = ():number => {
+        return this.nElements;
+    }
+
+    /**
+     * Returns true if this dictionary contains no mappings.
+     * @return {boolean} true if this dictionary contains no mappings.
+     */
+    isEmpty = ():boolean => {
+        return this.nElements <= 0;
+    }
+
+    toString = ():string => {
+        let toret = "{";
+        this.forEach((k, v) => {
+            toret = toret + "\n\t" + k.toString() + " : " + v.toString();
+        });
+        return toret + "\n}";
+    }
+} // End of dictionary
+
diff --git a/catalog-ui/src/app/utils/file-utils.ts b/catalog-ui/src/app/utils/file-utils.ts
new file mode 100644
index 0000000..d8c1822
--- /dev/null
+++ b/catalog-ui/src/app/utils/file-utils.ts
@@ -0,0 +1,51 @@
+export class FileUtils {
+
+    static '$inject' = [
+        '$window'
+    ];
+
+    constructor(private $window:any) {
+    }
+
+    public byteCharactersToBlob = (byteCharacters, contentType):any => {
+        contentType = contentType || '';
+        let sliceSize = 1024;
+        let bytesLength = byteCharacters.length;
+        let slicesCount = Math.ceil(bytesLength / sliceSize);
+        let byteArrays = new Array(slicesCount);
+
+        for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
+            let begin = sliceIndex * sliceSize;
+            let end = Math.min(begin + sliceSize, bytesLength);
+
+            let bytes = new Array(end - begin);
+            for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
+                bytes[i] = byteCharacters[offset].charCodeAt(0);
+            }
+            byteArrays[sliceIndex] = new Uint8Array(bytes);
+        }
+        return new Blob(byteArrays, {type: contentType});
+    };
+
+    public base64toBlob = (base64Data, contentType):any => {
+        let byteCharacters = atob(base64Data);
+        return this.byteCharactersToBlob(byteCharacters, contentType);
+    };
+
+    public downloadFile = (blob, fileName):void=> {
+        let url = this.$window.URL.createObjectURL(blob);
+        let downloadLink = document.createElement("a");
+
+        downloadLink.setAttribute('href', url);
+        downloadLink.setAttribute('download', fileName);
+        document.body.appendChild(downloadLink);
+
+        var clickEvent = new MouseEvent("click", {
+            "view": window,
+            "bubbles": true,
+            "cancelable": true
+        });
+        downloadLink.dispatchEvent(clickEvent);
+
+    }
+}
diff --git a/catalog-ui/src/app/utils/functions.ts b/catalog-ui/src/app/utils/functions.ts
new file mode 100644
index 0000000..24f8008
--- /dev/null
+++ b/catalog-ui/src/app/utils/functions.ts
@@ -0,0 +1,35 @@
+export class QueueUtils {
+
+    private executionQueue:any;
+
+    constructor(private $q:ng.IQService) {
+        this.executionQueue = this.getDummyPromise();
+    }
+
+
+    private getDummyPromise = ():ng.IPromise<boolean> => {
+        let deferred:ng.IDeferred<boolean> = this.$q.defer();
+        deferred.resolve(true);
+        return deferred.promise;
+    };
+
+
+    private addMethodToQueue = (runMe:Function):void => {
+        this.executionQueue = this.executionQueue.then(runMe, runMe);
+    };
+
+    addNonBlockingUIAction = (update:Function, releaseUIcallBack:Function):void => {
+        releaseUIcallBack();
+        this.addMethodToQueue(update);
+    };
+
+    // The Method call is responsible for releasing the UI
+    addBlockingUIAction = (blockingServerRequest:Function):void => {
+        this.addMethodToQueue(blockingServerRequest);
+    };
+
+    addBlockingUIActionWithReleaseCallback = (blockingServerRequest:Function, releaseUIcallBack:Function):void=> {
+        this.addMethodToQueue(blockingServerRequest);
+        this.addMethodToQueue(releaseUIcallBack);
+    };
+}
diff --git a/catalog-ui/src/app/utils/menu-handler.ts b/catalog-ui/src/app/utils/menu-handler.ts
new file mode 100644
index 0000000..1dc5a20
--- /dev/null
+++ b/catalog-ui/src/app/utils/menu-handler.ts
@@ -0,0 +1,125 @@
+'use strict';
+import {WorkspaceMode, ComponentState} from "./constants";
+import {IAppConfigurtaion, IAppMenu, Component} from "../models";
+import {ComponentFactory} from "./component-factory";
+import {ModalsHandler} from "./modals-handler";
+
+export class MenuItem {
+    text:string;
+    callback:(...args:Array<any>) => ng.IPromise<boolean>;
+    state:string;
+    action:string;
+    params:Array<any>;
+    isDisabled:boolean;
+    disabledRoles:Array<string>;
+    blockedForTypes:Array<string>;  // This item will not be shown for specific components types.
+
+    //TODO check if needed
+    alertModal:string;
+    conformanceLevelModal: boolean; // Call validateConformanceLevel API and shows conformanceLevelModal if necessary, then continue with action or invokes another action
+    confirmationModal:string;       // Open confirmation modal (user should select "OK" or "Cancel"), and continue with the action.
+    emailModal:string;              // Open email modal (user should fill email details), and continue with the action.
+    url:string;                     // Data added to menu item, in case the function need to use it, example: for function "changeLifecycleState", I need to pass also the state "CHECKOUT" that I want the state to change to.
+
+
+    constructor(text:string, callback:(...args:Array<any>) => ng.IPromise<boolean>, state:string, action:string, params?:Array<any>, blockedForTypes?:Array<string>) {
+        this.text = text;
+        this.callback = callback;
+        this.state = state;
+        this.action = action;
+        this.params = params;
+        this.blockedForTypes = blockedForTypes;
+    }
+}
+
+export class MenuItemGroup {
+    selectedIndex:number;
+    menuItems:Array<MenuItem>;
+    itemClick:boolean;
+
+    constructor(selectedIndex?:number, menuItems?:Array<MenuItem>, itemClick?:boolean) {
+        this.selectedIndex = selectedIndex;
+        this.menuItems = menuItems;
+        this.itemClick = itemClick;
+    }
+
+    public updateSelectedMenuItemText(newText:string) {
+        this.menuItems[this.selectedIndex].text = newText;
+    }
+}
+
+
+export class MenuHandler {
+
+    static '$inject' = [
+        'sdcConfig',
+        'sdcMenu',
+        'ComponentFactory',
+        '$filter',
+        'ModalsHandler',
+        '$state',
+        '$q'
+    ];
+
+    constructor(private sdcConfig:IAppConfigurtaion,
+                private sdcMenu:IAppMenu,
+                private ComponentFactory:ComponentFactory,
+                private $filter:ng.IFilterService,
+                private ModalsHandler:ModalsHandler,
+                private $state:ng.ui.IStateService,
+                private $q:ng.IQService) {
+
+    }
+
+
+    generateBreadcrumbsModelFromComponents = (components:Array<Component>, selected:Component):MenuItemGroup => {
+        let result = new MenuItemGroup(0, [], false);
+        if (components) {
+
+            // Search the component in all components by uuid (and not uniqueid, gives access to an assets's minor versions).
+            let selectedItem = _.find(components, (item:Component) => {
+                return item.uuid === selected.uuid;
+            });
+
+            // If not found search by invariantUUID
+            if (undefined == selectedItem) {
+                selectedItem = _.find(components, (item:Component) => {
+                    //invariantUUID && Certified State matches between major versions
+                    return item.invariantUUID === selected.invariantUUID && item.lifecycleState === ComponentState.CERTIFIED;
+                });
+            }
+
+            // If not found search by name (name is unique).
+            if (undefined == selectedItem) {
+                selectedItem = _.find(components, (item:Component) => {
+                    return item.name === selected.name;
+                });
+            }
+
+            result.selectedIndex = components.indexOf(selectedItem);
+            components[result.selectedIndex] = selected;
+            let clickItemCallback = (component:Component):ng.IPromise<boolean> => {
+                this.$state.go('workspace.general', {
+                    id: component.uniqueId,
+                    type: component.componentType.toLowerCase(),
+                    mode: WorkspaceMode.VIEW
+                });
+                return this.$q.when(true);
+            };
+
+            components.forEach((component:Component) => {
+                let menuItem = new MenuItem(
+                    //  component.name,
+                    component.getComponentSubType() + ': ' + this.$filter('resourceName')(component.name),
+                    clickItemCallback,
+                    null,
+                    null,
+                    [component]
+                );
+                //  menuItem.text = component.name;
+                result.menuItems.push(menuItem);
+            });
+        }
+        return result;
+    };
+}
diff --git a/catalog-ui/src/app/utils/modals-handler.ts b/catalog-ui/src/app/utils/modals-handler.ts
new file mode 100644
index 0000000..fe864cb
--- /dev/null
+++ b/catalog-ui/src/app/utils/modals-handler.ts
@@ -0,0 +1,389 @@
+import {PropertyModel, Component, ArtifactModel, Distribution, InputModel, DisplayModule, InputPropertyBase} from "../models";
+import {IEmailModalModel} from "../view-models/modals/email-modal/email-modal-view-model";
+import {IClientMessageModalModel} from "../view-models/modals/message-modal/message-client-modal/client-message-modal-view-model";
+import {IServerMessageModalModel} from "../view-models/modals/message-modal/message-server-modal/server-message-modal-view-model";
+import {IConfirmationModalModel} from "../view-models/modals/confirmation-modal/confirmation-modal-view-model";
+import {ModalType} from "./constants";
+import {AttributeModel} from "../models/attributes";
+
+export interface IModalsHandler {
+
+
+    openDistributionStatusModal (distribution:Distribution, status:string, component:Component):ng.IPromise<any>;
+    openConfirmationModal (title:string, message:string, showComment:boolean, size?:string):ng.IPromise<any>;
+    openAlertModal (title:string, message:string, size?:string):ng.IPromise<any>;
+    openEmailModal(emailModel:IEmailModalModel):ng.IPromise<any>;
+    openServerMessageModal(data:IServerMessageModalModel):ng.IPromise<any>;
+    openClientMessageModal(data:IClientMessageModalModel):ng.IPromise<ng.ui.bootstrap.IModalServiceInstance>;
+    openArtifactModal(artifact:ArtifactModel, component:Component):ng.IPromise<any>;
+    openEditPropertyModal(property:PropertyModel, component:Component, filteredProperties:Array<PropertyModel>, isPropertyOwnValue:boolean):ng.IPromise<any>;
+}
+
+export class ModalsHandler implements IModalsHandler {
+
+    static '$inject' = [
+        '$uibModal',
+        '$q'
+    ];
+
+    constructor(private $uibModal:ng.ui.bootstrap.IModalService,
+                private $q:ng.IQService) {
+    }
+
+
+
+
+    openDistributionStatusModal = (distribution:Distribution, status:string, component:Component):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view.html',
+            controller: 'Sdc.ViewModels.DistributionStatusModalViewModel',
+            size: 'sdc-xl',
+            backdrop: 'static',
+            resolve: {
+                data: ():any => {
+                    return {
+                        'distribution': distribution,
+                        'status': status,
+                        'component': component
+                    };
+                }
+            }
+        };
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+
+    openAlertModal = (title:string, message:string, size?:string):ng.IPromise<any> => {
+        return this.openConfirmationModalBase(title, message, false, ModalType.ALERT, size);
+    };
+
+    openConfirmationModal = (title:string, message:string, showComment:boolean, size?:string):ng.IPromise<any> => {
+        return this.openConfirmationModalBase(title, message, showComment, ModalType.STANDARD, size);
+    };
+
+    private openConfirmationModalBase = (title:string, message:string, showComment:boolean, type:ModalType, size?:string):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/modals/confirmation-modal/confirmation-modal-view.html',
+            controller: 'Sdc.ViewModels.ConfirmationModalViewModel',
+            size: size ? size : 'sdc-sm',
+            backdrop: 'static',
+            resolve: {
+                confirmationModalModel: ():IConfirmationModalModel => {
+                    let model:IConfirmationModalModel = {
+                        title: title,
+                        message: message,
+                        showComment: showComment,
+                        type: type
+                    };
+                    return model;
+                }
+            }
+        };
+
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+    openEmailModal = (emailModel:IEmailModalModel):ng.IPromise<any> => {
+
+        let deferred = this.$q.defer();
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/modals/email-modal/email-modal-view.html',
+            controller: 'Sdc.ViewModels.EmailModalViewModel',
+            size: 'sdc-sm',
+            backdrop: 'static',
+            resolve: {
+                emailModalModel: ():IEmailModalModel => {
+                    return emailModel;
+                }
+            }
+        };
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+
+    };
+
+    openServerMessageModal = (data:IServerMessageModalModel):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/modals/message-modal/message-server-modal/server-message-modal-view.html',
+            controller: 'Sdc.ViewModels.ServerMessageModalViewModel',
+            size: 'sdc-sm',
+            backdrop: 'static',
+            resolve: {
+                serverMessageModalModel: ():IServerMessageModalModel => {
+                    return data;
+                }
+            }
+        };
+
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+    openClientMessageModal = (data:IClientMessageModalModel):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/modals/message-modal/message-client-modal/client-message-modal-view.html',
+            controller: 'Sdc.ViewModels.ClientMessageModalViewModel',
+            size: 'sdc-sm',
+            backdrop: 'static',
+            resolve: {
+                clientMessageModalModel: ():IClientMessageModalModel => {
+                    return data;
+                }
+            }
+        };
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance);
+        return deferred.promise;
+    };
+
+    openOnboadrdingModal = (okButtonText:string, currentCsarUUID?:string):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/modals/onboarding-modal/onboarding-modal-view.html',
+            controller: 'Sdc.ViewModels.OnboardingModalViewModel',
+            size: 'sdc-xl',
+            backdrop: 'static',
+            resolve: {
+                okButtonText: ():string=> {
+                    return okButtonText;
+                },
+                currentCsarUUID: ():string=> {
+                    return currentCsarUUID || null;
+                }
+            }
+        };
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+    openEditEnvParametersModal = (artifactResource:ArtifactModel, component?:Component):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/forms/env-parameters-form/env-parameters-form.html',
+            controller: 'Sdc.ViewModels.EnvParametersFormViewModel',
+            size: 'sdc-xl',
+            backdrop: 'static',
+            resolve: {
+                artifact: ():ArtifactModel => {
+                    return artifactResource;
+                },
+                component: ():Component => {
+                    return component;
+                }
+            }
+        };
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+    openEditInputValueModal = (input:InputModel):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/forms/input-form/input-form-view.html',
+            controller: 'Sdc.ViewModels.InputFormViewModel',
+            size: 'sdc-md',
+            backdrop: 'static',
+            resolve: {
+                input: ():InputModel => {
+                    return input;
+                }
+            }
+        };
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+    openArtifactModal = (artifact:ArtifactModel, component:Component):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/forms/artifact-form/artifact-form-view.html',
+            controller: 'Sdc.ViewModels.ArtifactResourceFormViewModel',
+            size: 'sdc-md',
+            backdrop: 'static',
+            keyboard: false,
+            resolve: {
+                artifact: ():ArtifactModel => {
+                    return artifact;
+                },
+                component: ():Component => {
+                    return component;
+                }
+            }
+        };
+
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+
+    /**
+     *
+     * This function openes up the edit property modal
+     *
+     * @param property - the property to edit
+     * @param component - the component who is the owner of the property
+     * @param filteredProperties - the filtered properties list to scroll between in the edit modal
+     * @param isPropertyValueOwner - boolean telling if the component is eligible of editing the property
+     * @returns {IPromise<T>} - Promise telling if the modal has opened or not
+     */
+    openEditPropertyModal = (property:PropertyModel, component:Component, filteredProperties:Array<PropertyModel>, isPropertyValueOwner:boolean):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/forms/property-forms/component-property-form/property-form-view.html',
+            controller: 'Sdc.ViewModels.PropertyFormViewModel',
+            size: 'sdc-l',
+            backdrop: 'static',
+            keyboard: false,
+            resolve: {
+                property: ():PropertyModel => {
+                    return property;
+                },
+                component: ():Component => {
+                    return <Component> component;
+                },
+                filteredProperties: ():Array<PropertyModel> => {
+                    return filteredProperties;
+                },
+                isPropertyValueOwner: ():boolean => {
+                    return isPropertyValueOwner;
+                }
+            }
+        };
+
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+
+    openEditModulePropertyModal = (property:PropertyModel, component:Component, selectedModule:DisplayModule):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/forms/property-forms/base-property-form/property-form-base-view.html',
+            controller: 'Sdc.ViewModels.ModulePropertyView',
+            size: 'sdc-l',
+            backdrop: 'static',
+            keyboard: false,
+            resolve: {
+                originalProperty: ():PropertyModel => {
+                    return property;
+                },
+                component: ():Component => {
+                    return <Component> component;
+                },
+                selectedModule: ():DisplayModule => {
+                    return selectedModule;
+                }
+            }
+        };
+
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+    openSelectDataTypeModal = (property:PropertyModel, component:Component, filteredProperties:Array<PropertyModel>, propertiesMap:Array<InputPropertyBase>):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/forms/property-forms/base-property-form/property-form-base-view.html',
+            controller: 'Sdc.ViewModels.SelectDataTypeViewModel',
+            size: 'sdc-l',
+            backdrop: 'static',
+            keyboard: false,
+            resolve: {
+                originalProperty: ():PropertyModel => {
+                    return property;
+                },
+                component: ():Component => {
+                    return <Component> component;
+                },
+                filteredProperties: ():Array<PropertyModel> => {
+                    return filteredProperties;
+                },
+                propertiesMap: ():Array<InputPropertyBase>=> {
+                    return propertiesMap;
+                }
+            }
+        };
+
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+    public openEditAttributeModal = (attribute:AttributeModel, component: Component):void => {
+
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/forms/attribute-form/attribute-form-view.html',
+            controller: 'Sdc.ViewModels.AttributeFormViewModel',
+            size: 'sdc-md',
+            backdrop: 'static',
+            keyboard: false,
+            resolve: {
+                attribute: ():AttributeModel => {
+                    return attribute;
+                },
+                component: ():Component => {
+                    return component;
+                }
+            }
+        };
+        this.$uibModal.open(modalOptions);
+    };
+
+    public openUpdateComponentInstanceNameModal = (currentComponent: Component):ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/forms/resource-instance-name-form/resource-instance-name-view.html',
+            controller: 'Sdc.ViewModels.ResourceInstanceNameViewModel',
+            size: 'sdc-sm',
+            backdrop: 'static',
+            resolve: {
+                component: ():Component => {
+                    return currentComponent;
+                }
+            }
+        };
+
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance =  this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+    public openConformanceLevelModal = ():ng.IPromise<any> => {
+        let deferred = this.$q.defer();
+        let modalOptions:ng.ui.bootstrap.IModalSettings = {
+            templateUrl: '../view-models/workspace/conformance-level-modal/conformance-level-modal-view.html',
+            controller: 'Sdc.ViewModels.ConformanceLevelModalViewModel',
+            size: 'sdc-sm',
+            backdrop: 'static',
+            resolve: {
+
+            }
+        };
+
+        let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
+        deferred.resolve(modalInstance.result);
+        return deferred.promise;
+    };
+
+}
diff --git a/catalog-ui/src/app/utils/prototypes.ts b/catalog-ui/src/app/utils/prototypes.ts
new file mode 100644
index 0000000..2aa718a
--- /dev/null
+++ b/catalog-ui/src/app/utils/prototypes.ts
@@ -0,0 +1,64 @@
+interface String {
+    format(variables:Array<string>):string
+}
+
+interface Array<T> {
+    clean(o:T):Array<T>;
+}
+
+
+/**
+ * This function will replace the %<number> with strings (from array).
+ * Example: "Requested '%1' resource was not found.".format(["MyResource"]);
+ * Note: in case the array contains empty string the function will also remove the '' or the "".
+ */
+if (!String.hasOwnProperty("format")) {
+    String.prototype["format"] = function (variables:Array<string>):string {
+
+        if (variables === null || variables === undefined || variables.length === 0) {
+            variables = [''];
+        }
+
+        for (let i = 0; i < variables.length; i++) {
+            if (variables[i] === '' || variables[i] === null) {
+                variables[i] = '--DELETE--';
+            }
+        }
+
+        let res = this.replace(/%(\d+)/g, function (_, m) {
+            return variables[--m];
+        });
+
+        res = res.replace(" '--DELETE--' ", " ");
+        res = res.replace(" \"--DELETE--\" ", " ");
+        res = res.replace("'--DELETE--'", "");
+        res = res.replace("\"--DELETE--\"", "");
+        res = res.replace("--DELETE--", "");
+
+        return res;
+    };
+}
+
+if (!String.hasOwnProperty("capitalizeFirstLetter")) {
+    String.prototype["capitalizeFirstLetter"] = function () {
+        return this.charAt(0).toUpperCase() + this.slice(1);
+    };
+}
+
+if (!String.hasOwnProperty("replaceAll")) {
+    String.prototype["replaceAll"] = function (find:string, replace:string):string {
+        return this.replace(new RegExp(find, 'g'), replace);
+    };
+}
+
+if (!Array.hasOwnProperty("clean")) {
+    Array.prototype.clean = function (deleteValue) {
+        for (let i = 0; i < this.length; i++) {
+            if (this[i] == deleteValue) {
+                this.splice(i, 1);
+                i--;
+            }
+        }
+        return this;
+    };
+}
diff --git a/catalog-ui/src/app/utils/validation-utils.ts b/catalog-ui/src/app/utils/validation-utils.ts
new file mode 100644
index 0000000..9246d33
--- /dev/null
+++ b/catalog-ui/src/app/utils/validation-utils.ts
@@ -0,0 +1,153 @@
+class basePattern {
+    pattern:RegExp;
+    base:number;
+
+    constructor(pattern:RegExp, base:number) {
+        this.pattern = pattern;
+        this.base = base;
+    }
+}
+
+export interface IMapRegex {
+    integer:RegExp;
+    boolean:RegExp;
+    float:RegExp;
+    string:RegExp;
+}
+
+export class ValidationUtils {
+
+    static '$inject' = [
+        'IntegerNoLeadingZeroValidationPattern',
+        'FloatValidationPattern',
+        'CommentValidationPattern',
+        'BooleanValidationPattern',
+        'NumberValidationPattern',
+        'LabelValidationPattern',
+    ];
+    private trueRegex:string = '[t][r][u][e]|[t]|[o][n]|[y]|[y][e][s]|[1]';
+    private falseRegex:string = '[f][a][l][s][e]|[f]|[o][f][f]|[n]|[n][o]|[0]';
+    private heatBooleanValidationPattern:RegExp = new RegExp('^(' + this.trueRegex + '|' + this.falseRegex + ')$');
+
+
+    constructor(private IntegerNoLeadingZeroValidationPattern:RegExp,
+                private FloatValidationPattern:RegExp,
+                private CommentValidationPattern:RegExp,
+                private BooleanValidationPattern:RegExp,
+                private NumberValidationPattern:RegExp,
+                private LabelValidationPattern:RegExp) {
+    }
+
+    public stripAndSanitize(text:string):string {
+        if (!text) {
+            return null;
+        }
+        return text.replace(/\s+/g, ' ').replace(/%[A-Fa-f0-9]{2}/g, '').trim();
+    }
+
+    public getValidationPattern = (validationType:string, parameterType?:string):RegExp => {
+        switch (validationType) {
+            case 'integer':
+                return this.IntegerNoLeadingZeroValidationPattern;
+            case 'float':
+                return this.FloatValidationPattern;
+            case 'number':
+                return this.NumberValidationPattern;
+            case 'string':
+                return this.CommentValidationPattern;
+            case 'boolean':
+            {
+                //Bug Fix DE197437 [Patch]Mismatch between BE to FE regarding supported characters in Boolean filed
+                if (parameterType && parameterType === 'heat') {
+                    return this.heatBooleanValidationPattern;
+                }
+                else {
+                    return this.BooleanValidationPattern;
+                }
+            }
+
+            case 'label':
+                return this.LabelValidationPattern;
+            case 'category':
+                return this.LabelValidationPattern;
+            default :
+                return null;
+        }
+    };
+
+    public getPropertyListPatterns():IMapRegex {
+        return {
+            integer: /^(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)(,?(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+))*$/,
+            string: /^"[\u0000-\u0021\u0023-\u00BF]+"(\s*,?\s*"[\u0000-\u0021\u0023-\u00BF]+")*$/,
+            boolean: /^([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])(,?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]))*$/,
+            float: /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?(,?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?)*$/
+        };
+    }
+
+    public getPropertyMapPatterns():IMapRegex {
+        return {
+            integer: /^"\w+"\s*:\s?(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)+(\s*,?\s*"\w+"\s?:\s?(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)+)*$/,
+            string: /^"\w+"\s?:\s?"[\u0000-\u0021\u0023-\u00BF]*"(\s*,?\s*"\w+"\s?:\s?"[\u0000-\u0021\u0023-\u00BF]*")*$/,
+            boolean: /^"\w+"\s?:\s?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])(\s*,?\s*"\w+"\s?:\s?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]))*$/,
+            float: /^"\w+"\s?:\s?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?(\s*,?\s*"\w+"\s?:\s?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?)*$/
+        };
+    }
+
+    public validateUniqueKeys(viewValue:string):boolean {
+        if (!viewValue) {
+            return true; //allow empty value
+        }
+
+        let json:string = "{" + viewValue.replace(/\s\s+/g, ' ') + "}";
+        try {
+            let obj:any = JSON.parse(json);
+            /*
+             //Method #1 : check json string length before & after parsing
+             let newJson:string = JSON.stringify(obj);
+             if (newJson.length < json.length) {
+             return false;
+             }*/
+
+            //Method #2 : check how many times we can find "KEY": in json string
+            let result:boolean = true;
+            Object.keys(obj).forEach((key:string) => {
+                result = result && json.split('"' + key + '":').length === 2;
+            });
+            return result;
+
+        } catch (e) {
+            return false; //not a valid JSON
+        }
+
+        //return true;
+    }
+
+    public validateJson = (json:string):boolean => {
+        try {
+            JSON.parse(json);
+            return true;
+        } catch (err) {
+            console.log('invalid json');
+            return false;
+        }
+    };
+
+    public validateIntRange = (value:string):boolean => {
+
+        let base8 = new basePattern(/^([-+]?0o[0-7]+)$/, 8);
+        let base10 = new basePattern(/^(0|[-+]?[1-9][0-9]*)$/, 10);
+        let base16 = new basePattern(/^([-+]?0x[0-9a-fA-F]+)$/, 16);
+
+        let min:number = -0x80000000;
+        let max:number = 0x7fffffff;
+        let intPatterns:Array<basePattern> = [base8, base10, base16];
+        let matchedBase = _.find(intPatterns, (item)=> {
+            return item.pattern.test(value);
+        });
+
+        let parsed:number = parseInt(value.replace('o', ''), matchedBase.base);
+        if (parsed) {
+            return min <= parsed && max >= parsed;
+        }
+    }
+}