diff --git a/runtime/ui-react/src/components/dialogs/Policy/PolicyDeploymentEditor.js b/runtime/ui-react/src/components/dialogs/Policy/PolicyDeploymentEditor.js
index 57d6160..de29947 100644
--- a/runtime/ui-react/src/components/dialogs/Policy/PolicyDeploymentEditor.js
+++ b/runtime/ui-react/src/components/dialogs/Policy/PolicyDeploymentEditor.js
@@ -32,145 +32,147 @@
 import FormControlLabel from '@material-ui/core/FormControlLabel';
 
 const DivWhiteSpaceStyled = styled.div`
-    white-space: pre;
+  white-space: pre;
 `
 
 const PanelDiv = styled.div`
-    text-align: justify;
-    font-size: ${props => props.theme.policyEditorFontSize};
-    background-color: ${props => props.theme.loopViewerBackgroundColor};
+  text-align: justify;
+  font-size: ${ props => props.theme.policyEditorFontSize };
+  background-color: ${ props => props.theme.loopViewerBackgroundColor };
 `
 
 export default class PolicyDeploymentEditor extends React.Component {
 
-    state = {
-            policyData: this.props.policyData,
-            showSuccessAlert: false,
-            showFailAlert: false,
-            checkboxesState: this.createPdpStructure(this.props.policyData),
-            checkboxesInitialState: this.createPdpStructure(this.props.policyData),
-    };
+  state = {
+    policyData: this.props.policyData,
+    showSuccessAlert: false,
+    showFailAlert: false,
+    checkboxesState: this.createPdpStructure(this.props.policyData),
+    checkboxesInitialState: this.createPdpStructure(this.props.policyData),
+  };
 
-    constructor(props, context) {
-        super(props, context);
-        this.handleClose = this.handleClose.bind(this);
-        this.handleUpdatePdpDeployment = this.handleUpdatePdpDeployment.bind(this);
-        this.disableAlert = this.disableAlert.bind(this);
-        this.renderPdpDeploymentCheckboxes = this.renderPdpDeploymentCheckboxes.bind(this);
-        this.createPdpStructure = this.createPdpStructure.bind(this);
-        this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
-        this.createPdpGroupOperations = this.createPdpGroupOperations.bind(this);
+  constructor(props, context) {
+    super(props, context);
+    this.handleClose = this.handleClose.bind(this);
+    this.handleUpdatePdpDeployment = this.handleUpdatePdpDeployment.bind(this);
+    this.disableAlert = this.disableAlert.bind(this);
+    this.renderPdpDeploymentCheckboxes = this.renderPdpDeploymentCheckboxes.bind(this);
+    this.createPdpStructure = this.createPdpStructure.bind(this);
+    this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
+    this.createPdpGroupOperations = this.createPdpGroupOperations.bind(this);
+  }
+
+  handleClose() {
+    this.setState({ show: false });
+
+  }
+
+  disableAlert() {
+    this.setState({ showSuccessAlert: false, showFailAlert: false });
+  }
+
+  createPdpGroupOperations(initialStates, newStates) {
+    let commandsArray = [];
+    initialStates.forEach(initElem => {
+      let newStateFound = newStates.find(newElement => newElement.name === initElem.name);
+      if (initElem.value !== newStateFound.value) {
+        let newPdpGroupsArray = newStateFound.name.split("/");
+        let operation = "POST/";
+        if (initElem.value) {
+          operation = "DELETE/";
+        }
+        commandsArray.push(operation + newPdpGroupsArray[0] + "/" + newPdpGroupsArray[1] + "/"
+          + this.state.policyData.name + "/" + this.state.policyData.version);
+      }
+    });
+    return commandsArray.length > 0 ? { "PdpActions": commandsArray } : undefined;
+  }
+
+  handleUpdatePdpDeployment() {
+    let operationsList = this.createPdpGroupOperations(this.state.checkboxesInitialState,
+      this.state.checkboxesState);
+    if (typeof (operationsList) !== "undefined") {
+      PolicyService.updatePdpDeployment(operationsList).then(respPdpDeploymentUpdate => {
+        if (typeof (respPdpDeploymentUpdate) === "undefined") {
+          //it indicates a failure
+          this.setState({
+            showFailAlert: true,
+            showMessage: 'Pdp Deployment update Failure'
+          });
+        } else {
+          this.setState({
+            showSuccessAlert: true,
+            showMessage: 'Pdp Deployment Update successful'
+          });
+          this.props.policiesTableUpdateFunction();
+        }
+      })
+    } else {
+      this.setState({
+        showSuccessAlert: true,
+        showMessage: 'Pdp Deployment: Nothing to change'
+      });
     }
+  }
 
-    handleClose() {
-        this.setState({ show: false });
-
-    }
-
-    disableAlert() {
-        this.setState ({ showSuccessAlert: false, showFailAlert: false });
-    }
-
-    createPdpGroupOperations(initialStates, newStates) {
-        let commandsArray = [];
-        initialStates.forEach(initElem => {
-            let newStateFound = newStates.find(newElement => newElement.name === initElem.name);
-            if (initElem.value !== newStateFound.value) {
-                let newPdpGroupsArray = newStateFound.name.split("/");
-                let operation = "POST/";
-                if (initElem.value) {
-                    operation = "DELETE/";
-                }
-                commandsArray.push(operation + newPdpGroupsArray[0] + "/"+newPdpGroupsArray[1] + "/"
-                    +this.state.policyData.name + "/" + this.state.policyData.version);
-            }
+  createPdpStructure(policyData) {
+    // Create map with data for all group/subgroup where the policy is deployed
+    let infoPdpMap = new Map();
+    if (typeof policyData.pdpGroupInfo !== "undefined") {
+      policyData["pdpGroupInfo"].forEach(pdpGroupElem => {
+        let pdpGroupName = Object.keys(pdpGroupElem)[0];
+        pdpGroupElem[pdpGroupName]["pdpSubgroups"].forEach(pdpSubGroupElem => {
+          infoPdpMap.set(pdpGroupName + "/" + pdpSubGroupElem["pdpType"], true);
         });
-        return commandsArray.length > 0 ? {"PdpActions":commandsArray} : undefined;
+      });
     }
+    // Create the possible values for pdpgroup/subgroup and tick the ones where policy is deployed
+    let pdpStates = [];
+    if (typeof policyData.supportedPdpGroups !== "undefined") {
+      for (const pdpGroup of policyData["supportedPdpGroups"]) {
+        let pdpGroupName = Object.keys(pdpGroup)[0];
+        for (const pdpSubGroup of Object.values(pdpGroup)[0]) {
+          let fullName = pdpGroupName + "/" + pdpSubGroup;
+          pdpStates.push({
+            name: fullName,
+            value: infoPdpMap.get(fullName) !== undefined
+          });
+        }
+      }
+    }
+    return pdpStates;
+  }
 
-    handleUpdatePdpDeployment() {
-            let operationsList = this.createPdpGroupOperations(this.state.checkboxesInitialState,
-                                                 this.state.checkboxesState);
-            if (typeof(operationsList) !== "undefined") {
-                PolicyService.updatePdpDeployment(operationsList).then(respPdpDeploymentUpdate => {
-                    if (typeof(respPdpDeploymentUpdate) === "undefined") {
-                        //it indicates a failure
-                        this.setState({
-                            showFailAlert: true,
-                            showMessage: 'Pdp Deployment update Failure'
-                        });
-                    } else {
-                        this.setState({
-                            showSuccessAlert: true,
-                            showMessage: 'Pdp Deployment Update successful'
-                        });
-                        this.props.policiesTableUpdateFunction();
-                    }
-                })
-            } else {
-                this.setState({
-                    showSuccessAlert: true,
-                    showMessage: 'Pdp Deployment: Nothing to change'
-                });
-            }
-    }
+  handleCheckboxChange(event) {
+    const checkboxesArray = this.state.checkboxesState;
+    checkboxesArray.find(element => element.name === event.target.name).value = event.target.checked;
+    this.setState({ checkboxesState: checkboxesArray });
+  }
 
-    createPdpStructure(policyData) {
-            // Create map with data for all group/subgroup where the policy is deployed
-            let infoPdpMap = new Map();
-            if (typeof policyData.pdpGroupInfo !== "undefined") {
-                policyData["pdpGroupInfo"].forEach(pdpGroupElem => {
-                    let pdpGroupName = Object.keys(pdpGroupElem)[0];
-                    pdpGroupElem[pdpGroupName]["pdpSubgroups"].forEach(pdpSubGroupElem => {
-                        infoPdpMap.set(pdpGroupName + "/" + pdpSubGroupElem["pdpType"], true);
-                    });
-                });
-            }
-            // Create the possible values for pdpgroup/subgroup and tick the ones where policy is deployed
-            let pdpStates = [];
-            if (typeof policyData.supportedPdpGroups !== "undefined") {
-                for (const pdpGroup of policyData["supportedPdpGroups"]) {
-                    let pdpGroupName = Object.keys(pdpGroup)[0];
-                    for (const pdpSubGroup of Object.values(pdpGroup)[0]) {
-                            let fullName = pdpGroupName + "/" + pdpSubGroup;
-                            pdpStates.push({name: fullName,
-                                value: infoPdpMap.get(fullName) !== undefined});
-                    }
-                }
-            }
-            return pdpStates;
-    }
+  renderPdpDeploymentCheckboxes() {
+    return this.state.checkboxesState.map(item => {
+      return <FormControlLabel control={ <Checkbox checked={ item.value } onChange={ this.handleCheckboxChange }
+                                                   name={ item.name }/> } label={ item.name }/>;
+    });
+  }
 
-    handleCheckboxChange(event) {
-        const checkboxesArray = this.state.checkboxesState;
-        checkboxesArray.find(element => element.name === event.target.name).value = event.target.checked;
-        this.setState({checkboxesState:checkboxesArray});
-    }
-
-    renderPdpDeploymentCheckboxes() {
-        return this.state.checkboxesState.map(item => {
-            return <FormControlLabel control={<Checkbox checked={item.value} onChange={this.handleCheckboxChange}
-                name={item.name} />} label={item.name} />;
-        });
-    }
-
-    render() {
-     return (
-        <PanelDiv>
-          <Alert variant="success" show={this.state.showSuccessAlert} onClose={this.disableAlert} dismissible>
-              <DivWhiteSpaceStyled>
-                  {this.state.showMessage}
-              </DivWhiteSpaceStyled>
-          </Alert>
-          <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible>
-              <DivWhiteSpaceStyled>
-                  {this.state.showMessage}
-              </DivWhiteSpaceStyled>
-          </Alert>
-          <Button variant="secondary" title="Update the policy to the specified PDP Groups/Subgroups"
-            onClick={this.handleUpdatePdpDeployment}>Update PDP</Button>
-          <FormGroup>{this.renderPdpDeploymentCheckboxes()}</FormGroup>
-        </PanelDiv>
-       );
-    }
- }
\ No newline at end of file
+  render() {
+    return (
+      <PanelDiv>
+        <Alert variant="success" show={ this.state.showSuccessAlert } onClose={ this.disableAlert } dismissible>
+          <DivWhiteSpaceStyled>
+            { this.state.showMessage }
+          </DivWhiteSpaceStyled>
+        </Alert>
+        <Alert variant="danger" show={ this.state.showFailAlert } onClose={ this.disableAlert } dismissible>
+          <DivWhiteSpaceStyled>
+            { this.state.showMessage }
+          </DivWhiteSpaceStyled>
+        </Alert>
+        <Button variant="secondary" title="Update the policy to the specified PDP Groups/Subgroups"
+                onClick={ this.handleUpdatePdpDeployment }>Update PDP</Button>
+        <FormGroup>{ this.renderPdpDeploymentCheckboxes() }</FormGroup>
+      </PanelDiv>
+    );
+  }
+}
diff --git a/runtime/ui-react/src/components/dialogs/Policy/PolicyModal.js b/runtime/ui-react/src/components/dialogs/Policy/PolicyModal.js
index 4a883ff..0c7637c 100644
--- a/runtime/ui-react/src/components/dialogs/Policy/PolicyModal.js
+++ b/runtime/ui-react/src/components/dialogs/Policy/PolicyModal.js
@@ -31,315 +31,319 @@
 import styled from 'styled-components';
 import LoopService from '../../../api/LoopService';
 import LoopCache from '../../../api/LoopCache';
-import { JSONEditor }  from '@json-editor/json-editor/dist/jsoneditor.js';
+import { JSONEditor } from '@json-editor/json-editor/dist/jsoneditor.js';
 import "@fortawesome/fontawesome-free/css/all.css"
 import Alert from 'react-bootstrap/Alert';
 import OnapConstant from '../../../utils/OnapConstants';
 import OnapUtils from '../../../utils/OnapUtils';
 
 const ModalStyled = styled(Modal)`
-    background-color: transparent;
+  background-color: transparent;
 `
 
 const DivWhiteSpaceStyled = styled.div`
-    white-space: pre;
+  white-space: pre;
 `
 
 export default class PolicyModal extends React.Component {
 
-    state = {
-        show: true,
-        loopCache: this.props.loopCache,
-        jsonEditor: null,
-        policyName: this.props.match.params.policyName,
-        // This is to indicate whether it's an operational or config policy (in terms of loop instance)
-        policyInstanceType: this.props.match.params.policyInstanceType,
-        pdpGroup: null,
-        pdpGroupList: [],
-        pdpSubgroupList: [],
-        chosenPdpGroup: '',
+  state = {
+    show: true,
+    loopCache: this.props.loopCache,
+    jsonEditor: null,
+    policyName: this.props.match.params.policyName,
+    // This is to indicate whether it's an operational or config policy (in terms of loop instance)
+    policyInstanceType: this.props.match.params.policyInstanceType,
+    pdpGroup: null,
+    pdpGroupList: [],
+    pdpSubgroupList: [],
+    chosenPdpGroup: '',
+    chosenPdpSubgroup: '',
+    showSucAlert: false,
+    showFailAlert: false
+  };
+
+  constructor(props, context) {
+    super(props, context);
+    this.handleClose = this.handleClose.bind(this);
+    this.handleSave = this.handleSave.bind(this);
+    this.renderJsonEditor = this.renderJsonEditor.bind(this);
+    this.handlePdpGroupChange = this.handlePdpGroupChange.bind(this);
+    this.handlePdpSubgroupChange = this.handlePdpSubgroupChange.bind(this);
+    this.createJsonEditor = this.createJsonEditor.bind(this);
+    this.handleRefresh = this.handleRefresh.bind(this);
+    this.disableAlert = this.disableAlert.bind(this);
+    this.renderPdpGroupDropDown = this.renderPdpGroupDropDown.bind(this);
+    this.renderOpenLoopMessage = this.renderOpenLoopMessage.bind(this);
+    this.renderModalTitle = this.renderModalTitle.bind(this);
+    this.readOnly = props.readOnly !== undefined ? props.readOnly : false;
+  }
+
+  handleSave() {
+    var editorData = this.state.jsonEditor.getValue();
+    var errors = this.state.jsonEditor.validate();
+    errors = errors.concat(this.customValidation(editorData, this.state.loopCache.getTemplateName()));
+
+    if (errors.length !== 0) {
+      console.error("Errors detected during policy data validation ", errors);
+      this.setState({
+        showFailAlert: true,
+        showMessage: 'Errors detected during policy data validation:\n' + OnapUtils.jsonEditorErrorFormatter(errors)
+      });
+      return;
+    } else {
+      console.info("NO validation errors found in policy data");
+      if (this.state.policyInstanceType === OnapConstant.microServiceType) {
+        this.state.loopCache.updateMicroServiceProperties(this.state.policyName, editorData);
+        this.state.loopCache.updateMicroServicePdpGroup(this.state.policyName, this.state.chosenPdpGroup, this.state.chosenPdpSubgroup);
+        LoopService.setMicroServiceProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getMicroServiceForName(this.state.policyName)).then(resp => {
+          this.setState({ show: false });
+          this.props.history.push('/');
+          this.props.loadLoopFunction(this.state.loopCache.getLoopName());
+        });
+      } else if (this.state.policyInstanceType === OnapConstant.operationalPolicyType) {
+        this.state.loopCache.updateOperationalPolicyProperties(this.state.policyName, editorData);
+        this.state.loopCache.updateOperationalPolicyPdpGroup(this.state.policyName, this.state.chosenPdpGroup, this.state.chosenPdpSubgroup);
+        LoopService.setOperationalPolicyProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getOperationalPolicies()).then(resp => {
+          this.setState({ show: false });
+          this.props.history.push('/');
+          this.props.loadLoopFunction(this.state.loopCache.getLoopName());
+        });
+      }
+    }
+  }
+
+  customValidation(editorData, templateName) {
+    // method for sub-classes to override with customized validation
+    return [];
+  }
+
+  handleClose() {
+    this.setState({ show: false });
+    this.props.history.push('/');
+  }
+
+  componentDidMount() {
+    this.renderJsonEditor();
+  }
+
+  componentDidUpdate() {
+    if (this.state.showSucAlert === true || this.state.showFailAlert === true) {
+      let modalElement = document.getElementById("policyModal")
+      if (modalElement) {
+        modalElement.scrollTo(0, 0);
+      }
+    }
+  }
+
+  createJsonEditor(toscaModel, editorData) {
+    return new JSONEditor(document.getElementById("editor"),
+      {
+        schema: toscaModel,
+        startval: editorData,
+        theme: 'bootstrap4',
+        iconlib: 'fontawesome5',
+        object_layout: 'grid',
+        disable_properties: false,
+        disable_edit_json: false,
+        disable_array_reorder: true,
+        disable_array_delete_last_row: true,
+        disable_array_delete_all_rows: false,
+        array_controls_top: true,
+        keep_oneof_values: false,
+        collapsed: true,
+        show_errors: 'always',
+        display_required_only: false,
+        show_opt_in: false,
+        prompt_before_delete: true,
+        required_by_default: false
+      })
+  }
+
+  renderJsonEditor() {
+    console.debug("Rendering PolicyModal ", this.state.policyName);
+    var toscaModel = {};
+    var editorData = {};
+    var pdpGroupValues = {};
+    var chosenPdpGroupValue, chosenPdpSubgroupValue;
+    if (this.state.policyInstanceType === OnapConstant.microServiceType) {
+      toscaModel = this.state.loopCache.getMicroServiceJsonRepresentationForName(this.state.policyName);
+      editorData = this.state.loopCache.getMicroServicePropertiesForName(this.state.policyName);
+      pdpGroupValues = this.state.loopCache.getMicroServiceSupportedPdpGroup(this.state.policyName);
+      chosenPdpGroupValue = this.state.loopCache.getMicroServicePdpGroup(this.state.policyName);
+      chosenPdpSubgroupValue = this.state.loopCache.getMicroServicePdpSubgroup(this.state.policyName);
+    } else if (this.state.policyInstanceType === OnapConstant.operationalPolicyType) {
+      toscaModel = this.state.loopCache.getOperationalPolicyJsonRepresentationForName(this.state.policyName);
+      editorData = this.state.loopCache.getOperationalPolicyPropertiesForName(this.state.policyName);
+      pdpGroupValues = this.state.loopCache.getOperationalPolicySupportedPdpGroup(this.state.policyName);
+      chosenPdpGroupValue = this.state.loopCache.getOperationalPolicyPdpGroup(this.state.policyName);
+      chosenPdpSubgroupValue = this.state.loopCache.getOperationalPolicyPdpSubgroup(this.state.policyName);
+    }
+
+    if (toscaModel == null) {
+      return;
+    }
+
+    var pdpSubgroupValues = [];
+    if (typeof (chosenPdpGroupValue) !== "undefined") {
+      var selectedPdpGroup = pdpGroupValues.filter(entry => (Object.keys(entry)[0] === chosenPdpGroupValue));
+      pdpSubgroupValues = selectedPdpGroup[0][chosenPdpGroupValue].map((pdpSubgroup) => {
+        return { label: pdpSubgroup, value: pdpSubgroup }
+      });
+    }
+    this.setState({
+      jsonEditor: this.createJsonEditor(toscaModel, editorData),
+      pdpGroup: pdpGroupValues,
+      pdpGroupList: pdpGroupValues.map(entry => {
+        return { label: Object.keys(entry)[0], value: Object.keys(entry)[0] };
+      }),
+      pdpSubgroupList: pdpSubgroupValues,
+      chosenPdpGroup: chosenPdpGroupValue,
+      chosenPdpSubgroup: chosenPdpSubgroupValue
+    })
+  }
+
+  handlePdpGroupChange(e) {
+    var selectedPdpGroup = this.state.pdpGroup.filter(entry => (Object.keys(entry)[0] === e.value));
+    const pdpSubgroupValues = selectedPdpGroup[0][e.value].map((pdpSubgroup) => {
+      return { label: pdpSubgroup, value: pdpSubgroup }
+    });
+    if (this.state.chosenPdpGroup !== e.value) {
+      this.setState({
+        chosenPdpGroup: e.value,
         chosenPdpSubgroup: '',
-        showSucAlert: false,
-        showFailAlert: false
-    };
-
-    constructor(props, context) {
-        super(props, context);
-        this.handleClose = this.handleClose.bind(this);
-        this.handleSave = this.handleSave.bind(this);
-        this.renderJsonEditor = this.renderJsonEditor.bind(this);
-        this.handlePdpGroupChange = this.handlePdpGroupChange.bind(this);
-        this.handlePdpSubgroupChange = this.handlePdpSubgroupChange.bind(this);
-        this.createJsonEditor = this.createJsonEditor.bind(this);
-        this.handleRefresh = this.handleRefresh.bind(this);
-        this.disableAlert =  this.disableAlert.bind(this);
-        this.renderPdpGroupDropDown = this.renderPdpGroupDropDown.bind(this);
-        this.renderOpenLoopMessage = this.renderOpenLoopMessage.bind(this);
-        this.renderModalTitle = this.renderModalTitle.bind(this);
-        this.readOnly = props.readOnly !== undefined ? props.readOnly : false;
+        pdpSubgroupList: pdpSubgroupValues
+      });
     }
+  }
 
-    handleSave() {
-        var editorData = this.state.jsonEditor.getValue();
-        var errors = this.state.jsonEditor.validate();
-        errors = errors.concat(this.customValidation(editorData, this.state.loopCache.getTemplateName()));
+  handlePdpSubgroupChange(e) {
+    this.setState({ chosenPdpSubgroup: e.value });
+  }
 
-        if (errors.length !== 0) {
-            console.error("Errors detected during policy data validation ", errors);
-            this.setState({
-                showFailAlert: true,
-                showMessage: 'Errors detected during policy data validation:\n' + OnapUtils.jsonEditorErrorFormatter(errors)
-            });
-            return;
-        }
-        else {
-            console.info("NO validation errors found in policy data");
-            if (this.state.policyInstanceType === OnapConstant.microServiceType) {
-                this.state.loopCache.updateMicroServiceProperties(this.state.policyName, editorData);
-                this.state.loopCache.updateMicroServicePdpGroup(this.state.policyName, this.state.chosenPdpGroup, this.state.chosenPdpSubgroup);
-                LoopService.setMicroServiceProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getMicroServiceForName(this.state.policyName)).then(resp => {
-                    this.setState({ show: false });
-                    this.props.history.push('/');
-                    this.props.loadLoopFunction(this.state.loopCache.getLoopName());
-                });
-            } else if (this.state.policyInstanceType === OnapConstant.operationalPolicyType) {
-                this.state.loopCache.updateOperationalPolicyProperties(this.state.policyName, editorData);
-                this.state.loopCache.updateOperationalPolicyPdpGroup(this.state.policyName, this.state.chosenPdpGroup, this.state.chosenPdpSubgroup);
-                LoopService.setOperationalPolicyProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getOperationalPolicies()).then(resp => {
-                    this.setState({ show: false });
-                    this.props.history.push('/');
-                    this.props.loadLoopFunction(this.state.loopCache.getLoopName());
-                });
-            }
-        }
-    }
-
-    customValidation(editorData, templateName) {
-        // method for sub-classes to override with customized validation
-        return [];
-    }
-
-    handleClose() {
-        this.setState({ show: false });
-        this.props.history.push('/');
-    }
-
-    componentDidMount() {
-        this.renderJsonEditor();
-    }
-
-    componentDidUpdate() {
-        if (this.state.showSucAlert === true || this.state.showFailAlert === true) {
-            let modalElement = document.getElementById("policyModal")
-            if (modalElement) {
-                modalElement.scrollTo(0, 0);
-            }
-        }
-    }
-
-    createJsonEditor(toscaModel, editorData) {
-        return new JSONEditor(document.getElementById("editor"),
-        {   schema: toscaModel,
-              startval: editorData,
-              theme: 'bootstrap4',
-              iconlib: 'fontawesome5',
-              object_layout: 'grid',
-              disable_properties: false,
-              disable_edit_json: false,
-              disable_array_reorder: true,
-              disable_array_delete_last_row: true,
-              disable_array_delete_all_rows: false,
-              array_controls_top: true,
-              keep_oneof_values: false,
-              collapsed:true,
-              show_errors: 'always',
-              display_required_only: false,
-              show_opt_in: false,
-              prompt_before_delete: true,
-              required_by_default: false
-        })
-    }
-
-    renderJsonEditor() {
-        console.debug("Rendering PolicyModal ", this.state.policyName);
-        var toscaModel = {};
-        var editorData = {};
-        var pdpGroupValues = {};
-        var chosenPdpGroupValue, chosenPdpSubgroupValue;
-        if (this.state.policyInstanceType === OnapConstant.microServiceType) {
-            toscaModel = this.state.loopCache.getMicroServiceJsonRepresentationForName(this.state.policyName);
-            editorData = this.state.loopCache.getMicroServicePropertiesForName(this.state.policyName);
-            pdpGroupValues = this.state.loopCache.getMicroServiceSupportedPdpGroup(this.state.policyName);
-            chosenPdpGroupValue = this.state.loopCache.getMicroServicePdpGroup(this.state.policyName);
-            chosenPdpSubgroupValue = this.state.loopCache.getMicroServicePdpSubgroup(this.state.policyName);
-        } else if (this.state.policyInstanceType === OnapConstant.operationalPolicyType) {
-            toscaModel = this.state.loopCache.getOperationalPolicyJsonRepresentationForName(this.state.policyName);
-            editorData = this.state.loopCache.getOperationalPolicyPropertiesForName(this.state.policyName);
-            pdpGroupValues = this.state.loopCache.getOperationalPolicySupportedPdpGroup(this.state.policyName);
-            chosenPdpGroupValue = this.state.loopCache.getOperationalPolicyPdpGroup(this.state.policyName);
-            chosenPdpSubgroupValue = this.state.loopCache.getOperationalPolicyPdpSubgroup(this.state.policyName);
-        }
-
-        if (toscaModel == null) {
-            return;
-        }
-
-        var pdpSubgroupValues = [];
-        if (typeof(chosenPdpGroupValue) !== "undefined") {
-            var selectedPdpGroup =    pdpGroupValues.filter(entry => (Object.keys(entry)[0] === chosenPdpGroupValue));
-            pdpSubgroupValues = selectedPdpGroup[0][chosenPdpGroupValue].map((pdpSubgroup) => { return { label: pdpSubgroup, value: pdpSubgroup } });
-        }
+  handleRefresh() {
+    var newLoopCache, toscaModel, editorData;
+    if (this.state.policyInstanceType === OnapConstant.microServiceType) {
+      LoopService.refreshMicroServicePolicyJson(this.state.loopCache.getLoopName(), this.state.policyName).then(data => {
+        newLoopCache = new LoopCache(data);
+        toscaModel = newLoopCache.getMicroServiceJsonRepresentationForName(this.state.policyName);
+        editorData = newLoopCache.getMicroServicePropertiesForName(this.state.policyName);
+        document.getElementById("editor").innerHTML = "";
         this.setState({
-                        jsonEditor: this.createJsonEditor(toscaModel,editorData),
-                        pdpGroup: pdpGroupValues,
-                        pdpGroupList: pdpGroupValues.map(entry => {
-                                                      return { label: Object.keys(entry)[0], value: Object.keys(entry)[0] };
-                                              }),
-                        pdpSubgroupList: pdpSubgroupValues,
-                        chosenPdpGroup: chosenPdpGroupValue,
-                        chosenPdpSubgroup: chosenPdpSubgroupValue
-                    })
+          loopCache: newLoopCache,
+          jsonEditor: this.createJsonEditor(toscaModel, editorData),
+          showSucAlert: true,
+          showMessage: "Successfully refreshed"
+        });
+      })
+        .catch(error => {
+          console.error("Error while refreshing the Operational Policy Json Representation");
+          this.setState({
+            showFailAlert: true,
+            showMessage: "Refreshing of UI failed"
+          });
+        });
+    } else if (this.state.policyInstanceType === OnapConstant.operationalPolicyType) {
+      LoopService.refreshOperationalPolicyJson(this.state.loopCache.getLoopName(), this.state.policyName).then(data => {
+        var newLoopCache = new LoopCache(data);
+        toscaModel = newLoopCache.getOperationalPolicyJsonRepresentationForName(this.state.policyName);
+        editorData = newLoopCache.getOperationalPolicyPropertiesForName(this.state.policyName);
+        document.getElementById("editor").innerHTML = "";
+        this.setState({
+          loopCache: newLoopCache,
+          jsonEditor: this.createJsonEditor(toscaModel, editorData),
+          showSucAlert: true,
+          showMessage: "Successfully refreshed"
+        });
+      })
+        .catch(error => {
+          console.error("Error while refreshing the Operational Policy Json Representation");
+          this.setState({
+            showFailAlert: true,
+            showMessage: "Refreshing of UI failed"
+          });
+        });
     }
+  }
 
-    handlePdpGroupChange(e) {
-        var selectedPdpGroup =    this.state.pdpGroup.filter(entry => (Object.keys(entry)[0] === e.value));
-        const pdpSubgroupValues = selectedPdpGroup[0][e.value].map((pdpSubgroup) => { return { label: pdpSubgroup, value: pdpSubgroup } });
-        if (this.state.chosenPdpGroup !== e.value) {
-            this.setState({
-                chosenPdpGroup: e.value,
-                chosenPdpSubgroup: '',
-                pdpSubgroupList: pdpSubgroupValues
-            });
-        }
-    }
+  disableAlert() {
+    this.setState({ showSucAlert: false, showFailAlert: false });
+  }
 
-    handlePdpSubgroupChange(e) {
-        this.setState({ chosenPdpSubgroup: e.value });
+  renderPdpGroupDropDown() {
+    if (this.state.policyInstanceType !== OnapConstant.operationalPolicyType || !this.state.loopCache.isOpenLoopTemplate()) {
+      return (
+        <Form.Group as={ Row } controlId="formPlaintextEmail">
+          <Form.Label column sm="2">Pdp Group Info</Form.Label>
+          <Col sm="3">
+            <Select value={ { label: this.state.chosenPdpGroup, value: this.state.chosenPdpGroup } } onChange={ this.handlePdpGroupChange } options={ this.state.pdpGroupList }/>
+          </Col>
+          <Col sm="3">
+            <Select value={ { label: this.state.chosenPdpSubgroup, value: this.state.chosenPdpSubgroup } } onChange={ this.handlePdpSubgroupChange } options={ this.state.pdpSubgroupList }/>
+          </Col>
+        </Form.Group>
+      );
     }
+  }
 
-    handleRefresh() {
-        var newLoopCache, toscaModel, editorData;
-        if (this.state.policyInstanceType === OnapConstant.microServiceType) {
-            LoopService.refreshMicroServicePolicyJson(this.state.loopCache.getLoopName(),this.state.policyName).then(data => {
-                newLoopCache =  new LoopCache(data);
-                toscaModel = newLoopCache.getMicroServiceJsonRepresentationForName(this.state.policyName);
-                editorData = newLoopCache.getMicroServicePropertiesForName(this.state.policyName);
-                document.getElementById("editor").innerHTML = "";
-                this.setState({
-                    loopCache: newLoopCache,
-                    jsonEditor: this.createJsonEditor(toscaModel,editorData),
-                    showSucAlert: true,
-                    showMessage: "Successfully refreshed"
-                });
-            })
-            .catch(error => {
-                console.error("Error while refreshing the Operational Policy Json Representation");
-                this.setState({
-                    showFailAlert: true,
-                    showMessage: "Refreshing of UI failed"
-                });
-            });
-        } else if (this.state.policyInstanceType === OnapConstant.operationalPolicyType) {
-            LoopService.refreshOperationalPolicyJson(this.state.loopCache.getLoopName(),this.state.policyName).then(data => {
-                var newLoopCache =  new LoopCache(data);
-                toscaModel = newLoopCache.getOperationalPolicyJsonRepresentationForName(this.state.policyName);
-                editorData = newLoopCache.getOperationalPolicyPropertiesForName(this.state.policyName);
-                document.getElementById("editor").innerHTML = "";
-                this.setState({
-                    loopCache: newLoopCache,
-                    jsonEditor: this.createJsonEditor(toscaModel,editorData),
-                    showSucAlert: true,
-                    showMessage: "Successfully refreshed"
-                });
-            })
-            .catch(error => {
-                console.error("Error while refreshing the Operational Policy Json Representation");
-                this.setState({
-                    showFailAlert: true,
-                    showMessage: "Refreshing of UI failed"
-                });
-            });
-        }
+  renderOpenLoopMessage() {
+    if (this.state.policyInstanceType === OnapConstant.operationalPolicyType && this.state.loopCache.isOpenLoopTemplate()) {
+      return (
+        "Operational Policy cannot be configured as only Open Loop is supported for this Template!"
+      );
     }
+  }
 
-    disableAlert() {
-        this.setState ({ showSucAlert: false, showFailAlert: false });
-    }
+  renderModalTitle() {
+    return (
+      <Modal.Title>Edit the policy</Modal.Title>
+    );
+  }
 
-    renderPdpGroupDropDown() {
-        if(this.state.policyInstanceType !== OnapConstant.operationalPolicyType || !this.state.loopCache.isOpenLoopTemplate()) {
-            return (
-                <Form.Group as={Row} controlId="formPlaintextEmail">
-                    <Form.Label column sm="2">Pdp Group Info</Form.Label>
-                    <Col sm="3">
-                        <Select value={{ label: this.state.chosenPdpGroup, value: this.state.chosenPdpGroup }} onChange={this.handlePdpGroupChange} options={this.state.pdpGroupList} />
-                    </Col>
-                    <Col sm="3">
-                        <Select value={{ label: this.state.chosenPdpSubgroup, value: this.state.chosenPdpSubgroup }} onChange={this.handlePdpSubgroupChange} options={this.state.pdpSubgroupList} />
-                    </Col>
-                </Form.Group>
-            );
-        }
+  renderButton() {
+    var allElement = [(<Button key="close" variant="secondary" onClick={ this.handleClose }>
+      Close
+    </Button>)];
+    if (this.state.policyInstanceType !== OnapConstant.operationalPolicyType || !this.state.loopCache.isOpenLoopTemplate()) {
+      allElement.push((
+        <Button key="save" variant="primary" disabled={ this.readOnly } onClick={ this.handleSave }>
+          Save Changes
+        </Button>
+      ));
+      allElement.push((
+        <Button key="refresh" variant="primary" disabled={ this.readOnly } onClick={ this.handleRefresh }>
+          Refresh
+        </Button>
+      ));
     }
+    return allElement;
+  }
 
-    renderOpenLoopMessage() {
-        if(this.state.policyInstanceType === OnapConstant.operationalPolicyType && this.state.loopCache.isOpenLoopTemplate()) {
-            return (
-                   "Operational Policy cannot be configured as only Open Loop is supported for this Template!"
-               );
-           }
-    }
-
-    renderModalTitle() {
-        return (
-                <Modal.Title>Edit the policy</Modal.Title>
-        );
-    }
-
-    renderButton() {
-        var allElement = [(<Button key="close" variant="secondary" onClick={this.handleClose}>
-                                                   Close
-                         </Button>)];
-        if(this.state.policyInstanceType !== OnapConstant.operationalPolicyType || !this.state.loopCache.isOpenLoopTemplate()) {
-             allElement.push((
-                <Button key="save" variant="primary" disabled={this.readOnly} onClick={this.handleSave}>
-                                Save Changes
-                </Button>
-             ));
-             allElement.push((
-                <Button key="refresh" variant="primary" disabled={this.readOnly} onClick={this.handleRefresh}>
-                                Refresh
-                </Button>
-             ));
-        }
-        return allElement;
-    }
-
-    render() {
-        return (
-            <ModalStyled size="xl" backdrop="static" keyboard={false} show={this.state.show} onHide={this.handleClose}>
-                <Modal.Header closeButton>
-                    {this.renderModalTitle()}
-                </Modal.Header>
-                                <Alert variant="success" show={this.state.showSucAlert} onClose={this.disableAlert} dismissible>
-                                        <DivWhiteSpaceStyled>
-                                                {this.state.showMessage}
-                                        </DivWhiteSpaceStyled>
-                                </Alert>
-                                <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible>
-                                        <DivWhiteSpaceStyled>
-                                                {this.state.showMessage}
-                                        </DivWhiteSpaceStyled>
-                                </Alert>
-                <Modal.Body>
-                    {this.renderOpenLoopMessage()}
-                    <div id="editor" />
-                    {this.renderPdpGroupDropDown()}
-                </Modal.Body>
-                <Modal.Footer>
-                    {this.renderButton()}
-                </Modal.Footer>
-            </ModalStyled>
-        );
-    }
+  render() {
+    return (
+      <ModalStyled size="xl" backdrop="static" keyboard={ false } show={ this.state.show } onHide={ this.handleClose }>
+        <Modal.Header closeButton>
+          { this.renderModalTitle() }
+        </Modal.Header>
+        <Alert variant="success" show={ this.state.showSucAlert } onClose={ this.disableAlert } dismissible>
+          <DivWhiteSpaceStyled>
+            { this.state.showMessage }
+          </DivWhiteSpaceStyled>
+        </Alert>
+        <Alert variant="danger" show={ this.state.showFailAlert } onClose={ this.disableAlert } dismissible>
+          <DivWhiteSpaceStyled>
+            { this.state.showMessage }
+          </DivWhiteSpaceStyled>
+        </Alert>
+        <Modal.Body>
+          { this.renderOpenLoopMessage() }
+          <div id="editor"/>
+          { this.renderPdpGroupDropDown() }
+        </Modal.Body>
+        <Modal.Footer>
+          { this.renderButton() }
+        </Modal.Footer>
+      </ModalStyled>
+    );
+  }
 }
diff --git a/runtime/ui-react/src/components/dialogs/Policy/PolicyModal.test.js b/runtime/ui-react/src/components/dialogs/Policy/PolicyModal.test.js
index 1e6fac0..658b19e 100644
--- a/runtime/ui-react/src/components/dialogs/Policy/PolicyModal.test.js
+++ b/runtime/ui-react/src/components/dialogs/Policy/PolicyModal.test.js
@@ -29,107 +29,107 @@
 import { shallow } from 'enzyme';
 
 describe('Verify PolicyModal', () => {
-    beforeEach(() => {
-        fetch.resetMocks();
-        fetch.mockImplementation(() => {
-            return Promise.resolve({
-                ok: true,
-                status: 200,
-                text: () => "OK"
-            });
-        });
-    })
-    const loopCacheStr = {
-            "name": "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca",
-            "operationalPolicies": [{
-                "name": "OPERATIONAL_h2NMX_v1_0_ResourceInstanceName1_tca",
-                "configurationsJson": {
-                    "operational_policy": {
-                        "controlLoop": {},
-                        "policies": []
-                    }
-                },
-                "policyModel": {"policyPdpGroup": {"supportedPdpGroups":[{"monitoring": ["xacml"]}]}},
-                "jsonRepresentation" : {"schema": {}}
-             }]
-    };
-
-    const loopCache = new LoopCache(loopCacheStr);
-    const historyMock = { push: jest.fn() };
-    const flushPromises = () => new Promise(setImmediate);
-    const match = {params: {policyName:"OPERATIONAL_h2NMX_v1_0_ResourceInstanceName1_tca", policyInstanceType: OnapConstant.operationalPolicyType}}
-
-    it('Test handleClose', () => {
-      const handleClose = jest.spyOn(PolicyModal.prototype,'handleClose');
-      const component = mount(<PolicyModal history={historyMock} match={match} loopCache={loopCache}/>)
-
-      component.find('[variant="secondary"]').prop('onClick')();
-
-      expect(handleClose).toHaveBeenCalledTimes(1);
-      expect(component.state('show')).toEqual(false);
-      expect(historyMock.push.mock.calls[0]).toEqual([ '/']);
+  beforeEach(() => {
+    fetch.resetMocks();
+    fetch.mockImplementation(() => {
+      return Promise.resolve({
+        ok: true,
+        status: 200,
+        text: () => "OK"
+      });
     });
+  })
+  const loopCacheStr = {
+    "name": "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca",
+    "operationalPolicies": [{
+      "name": "OPERATIONAL_h2NMX_v1_0_ResourceInstanceName1_tca",
+      "configurationsJson": {
+        "operational_policy": {
+          "controlLoop": {},
+          "policies": []
+        }
+      },
+      "policyModel": { "policyPdpGroup": { "supportedPdpGroups": [{ "monitoring": ["xacml"] }] } },
+      "jsonRepresentation": { "schema": {} }
+    }]
+  };
 
-    it('Test handleSave', async () => {
-        const loadLoopFunction = jest.fn();
-        const handleSave = jest.spyOn(PolicyModal.prototype,'handleSave');
-        const component = mount(<PolicyModal history={historyMock} 
-                          loopCache={loopCache} match={match} loadLoopFunction={loadLoopFunction} />)
+  const loopCache = new LoopCache(loopCacheStr);
+  const historyMock = { push: jest.fn() };
+  const flushPromises = () => new Promise(setImmediate);
+  const match = { params: { policyName: "OPERATIONAL_h2NMX_v1_0_ResourceInstanceName1_tca", policyInstanceType: OnapConstant.operationalPolicyType } }
 
-        component.find('[variant="primary"]').get(0).props.onClick();
-        await flushPromises();
-        component.update();
+  it('Test handleClose', () => {
+    const handleClose = jest.spyOn(PolicyModal.prototype, 'handleClose');
+    const component = mount(<PolicyModal history={ historyMock } match={ match } loopCache={ loopCache }/>)
 
-        expect(handleSave).toHaveBeenCalledTimes(1);
-        expect(component.state('show')).toEqual(false);
-        expect(historyMock.push.mock.calls[0]).toEqual([ '/']);
+    component.find('[variant="secondary"]').prop('onClick')();
+
+    expect(handleClose).toHaveBeenCalledTimes(1);
+    expect(component.state('show')).toEqual(false);
+    expect(historyMock.push.mock.calls[0]).toEqual(['/']);
+  });
+
+  it('Test handleSave', async () => {
+    const loadLoopFunction = jest.fn();
+    const handleSave = jest.spyOn(PolicyModal.prototype, 'handleSave');
+    const component = mount(<PolicyModal history={ historyMock }
+                                         loopCache={ loopCache } match={ match } loadLoopFunction={ loadLoopFunction }/>)
+
+    component.find('[variant="primary"]').get(0).props.onClick();
+    await flushPromises();
+    component.update();
+
+    expect(handleSave).toHaveBeenCalledTimes(1);
+    expect(component.state('show')).toEqual(false);
+    expect(historyMock.push.mock.calls[0]).toEqual(['/']);
+  });
+
+  it('Test handleRefresh', async () => {
+    LoopService.refreshOperationalPolicyJson = jest.fn().mockImplementation(() => {
+      return Promise.resolve(loopCacheStr);
     });
+    const updateLoopFunction = jest.fn();
+    const handleRefresh = jest.spyOn(PolicyModal.prototype, 'handleRefresh');
+    const component = mount(<PolicyModal loopCache={ loopCache } match={ match } updateLoopFunction={ updateLoopFunction }/>)
 
-    it('Test handleRefresh', async () => {
-        LoopService.refreshOperationalPolicyJson = jest.fn().mockImplementation(() => {
-            return Promise.resolve(loopCacheStr);
-        });
-        const updateLoopFunction = jest.fn();
-        const handleRefresh = jest.spyOn(PolicyModal.prototype,'handleRefresh');
-        const component = mount(<PolicyModal loopCache={loopCache} match={match} updateLoopFunction={updateLoopFunction} />)
+    component.find('[variant="primary"]').get(1).props.onClick();
+    await flushPromises();
+    component.update();
 
-        component.find('[variant="primary"]').get(1).props.onClick();
-        await flushPromises();
-        component.update();
+    expect(handleRefresh).toHaveBeenCalledTimes(1);
+    expect(component.state('show')).toEqual(true);
+    expect(component.state('showSucAlert')).toEqual(true);
+    expect(component.state('showMessage')).toEqual("Successfully refreshed");
+  });
 
-        expect(handleRefresh).toHaveBeenCalledTimes(1);
-        expect(component.state('show')).toEqual(true);
-        expect(component.state('showSucAlert')).toEqual(true);
-        expect(component.state('showMessage')).toEqual("Successfully refreshed");
+  it('Test handlePdpGroupChange', () => {
+    const component = mount(<PolicyModal loopCache={ loopCache } match={ match }/>)
+    component.setState({
+      "pdpGroup": [{ "option1": ["subPdp1", "subPdp2"] }],
+      "chosenPdpGroup": "option2"
     });
+    expect(component.state('chosenPdpGroup')).toEqual("option2");
 
-    it('Test handlePdpGroupChange', () => {
-        const component = mount(<PolicyModal loopCache={loopCache} match={match} />)
-        component.setState({ 
-                "pdpGroup": [{"option1":["subPdp1","subPdp2"]}],
-                "chosenPdpGroup": "option2"
-        });
-        expect(component.state('chosenPdpGroup')).toEqual("option2");
+    const instance = component.instance();
+    const event = { label: "option1", value: "option1" }
+    instance.handlePdpGroupChange(event);
+    expect(component.state('chosenPdpGroup')).toEqual("option1");
+    expect(component.state('chosenPdpSubgroup')).toEqual("");
+    expect(component.state('pdpSubgroupList')).toEqual([{ label: "subPdp1", value: "subPdp1" }, { label: "subPdp2", value: "subPdp2" }]);
+  });
 
-        const instance = component.instance();
-        const event = {label:"option1", value:"option1"}
-        instance.handlePdpGroupChange(event);
-        expect(component.state('chosenPdpGroup')).toEqual("option1");
-        expect(component.state('chosenPdpSubgroup')).toEqual("");
-        expect(component.state('pdpSubgroupList')).toEqual([{label:"subPdp1", value:"subPdp1"}, {label:"subPdp2", value:"subPdp2"}]);
-    });
+  it('Test handlePdpSubgroupChange', () => {
+    const component = mount(<PolicyModal loopCache={ loopCache } match={ match }/>)
 
-    it('Test handlePdpSubgroupChange', () => {
-        const component = mount(<PolicyModal loopCache={loopCache} match={match} />)
+    const instance = component.instance();
+    const event = { label: "option1", value: "option1" }
+    instance.handlePdpSubgroupChange(event);
+    expect(component.state('chosenPdpSubgroup')).toEqual("option1");
+  });
 
-        const instance = component.instance();
-        const event = {label:"option1", value:"option1"}
-        instance.handlePdpSubgroupChange(event);
-        expect(component.state('chosenPdpSubgroup')).toEqual("option1");
-    });
-
-    it('Test the render method', () => {
-        const component = shallow(<PolicyModal loopCache={loopCache} match={match}/>)
-        expect(component).toMatchSnapshot();
-    });
-});
\ No newline at end of file
+  it('Test the render method', () => {
+    const component = shallow(<PolicyModal loopCache={ loopCache } match={ match }/>)
+    expect(component).toMatchSnapshot();
+  });
+});
diff --git a/runtime/ui-react/src/components/loop_viewer/svg/SvgGenerator.js b/runtime/ui-react/src/components/loop_viewer/svg/SvgGenerator.js
index 6d3cd7a..2692aef 100644
--- a/runtime/ui-react/src/components/loop_viewer/svg/SvgGenerator.js
+++ b/runtime/ui-react/src/components/loop_viewer/svg/SvgGenerator.js
@@ -27,220 +27,222 @@
 import OnapConstant from '../../../utils/OnapConstants';
 
 const DivStyled = styled.div`
-	overflow-x: scroll;
-	  display: flex;
-    width: 100%;
-    height: 100%;
+  overflow-x: scroll;
+  display: flex;
+  width: 100%;
+  height: 100%;
 `
 
-const emptySvg = (<svg> <text x="60" y="40">No LOOP (SVG)</text> </svg>);
+const emptySvg = (<svg>
+  <text x="60" y="40">No LOOP (SVG)</text>
+</svg>);
 
 class SvgGenerator extends React.Component {
-    boxWidth = 200;
-    boxHeight = 100;
-    boxSpace = 50;
+  boxWidth = 200;
+  boxHeight = 100;
+  boxSpace = 50;
 
-    static GENERATED_FROM_INSTANCE = "INSTANCE";
-    static GENERATED_FROM_TEMPLATE = "TEMPLATE";
+  static GENERATED_FROM_INSTANCE = "INSTANCE";
+  static GENERATED_FROM_TEMPLATE = "TEMPLATE";
 
-	state = {
-		loopCache: new LoopCache({}),
-		clickable: false,
-		generatedFrom: SvgGenerator.GENERATED_FROM_INSTANCE, // INSTANCE / TEMPLATE
-	}
+  state = {
+    loopCache: new LoopCache({}),
+    clickable: false,
+    generatedFrom: SvgGenerator.GENERATED_FROM_INSTANCE, // INSTANCE / TEMPLATE
+  }
 
-	constructor(props) {
-		super(props);
-		this.state.loopCache = props.loopCache;
-		this.state.clickable = props.clickable;
-		this.state.generatedFrom = props.generatedFrom;
-		this.handleSvgClick = this.handleSvgClick.bind(this);
-		this.renderSvg = this.renderSvg.bind(this);
-	}
+  constructor(props) {
+    super(props);
+    this.state.loopCache = props.loopCache;
+    this.state.clickable = props.clickable;
+    this.state.generatedFrom = props.generatedFrom;
+    this.handleSvgClick = this.handleSvgClick.bind(this);
+    this.renderSvg = this.renderSvg.bind(this);
+  }
 
-	shouldComponentUpdate(nextProps, nextState) {
-		return this.state.loopCache !== nextProps.loopCache;
-	}
+  shouldComponentUpdate(nextProps, nextState) {
+    return this.state.loopCache !== nextProps.loopCache;
+  }
 
-    componentDidUpdate(prevProps) {
-        if (prevProps.loopCache !== this.props.loopCache) {
-            this.setState({
-                loopCache: this.props.loopCache,
-            });
-        }
+  componentDidUpdate(prevProps) {
+    if (prevProps.loopCache !== this.props.loopCache) {
+      this.setState({
+        loopCache: this.props.loopCache,
+      });
+    }
+  }
+
+  handleSvgClick(event) {
+    console.debug("svg click event received");
+    if (this.state.clickable) {
+      var elementName = event.target.parentNode.getAttribute('policyId');
+      console.info("SVG element clicked", elementName);
+      // Only allow movement to policy editing IF there busyLoadingCOunt is 0,
+      // meaning we are not waiting for refreshStatus to complete, for example
+      if (elementName !== null && !this.props.isBusyLoading()) {
+        this.props.history.push("/policyModal/" + event.target.parentNode.getAttribute('policyType') + "/" + elementName);
+      }
+    }
+  }
+
+  createVesBox(xPos) {
+    return this.createOneBox(xPos, null, null, 'VES Collector', 'VES', null);
+  }
+
+  createOneArrow(xPos) {
+    return (
+      <svg width={ this.boxSpace } height={ this.boxHeight } x={ xPos }>
+        <defs>
+          <marker viewBox="0 0 20 20" markerWidth="20" markerHeight="20" orient="auto" refX="8.5" refY="5" id="arrow">
+            <path d="m 1 5 l 0 -3 l 7 3 l -7 3 z"
+                  stroke-width="1" stroke-linecap="butt" stroke-dasharray="10000, 1"
+                  fill="#000000" stroke="#000000"/>
+          </marker>
+        </defs>
+        <line x1="0" y1="50%" x2="100%" y2="50%" stroke-width="2" color="black" stroke="black" marker-end="url(#arrow)"/>
+      </svg>
+    );
+  }
+
+  createBeginCircle(xPos, text) {
+    return (
+      <svg width={ this.boxWidth } height={ this.boxHeight } x={ xPos }>
+        <circle cx={ this.boxWidth - 30 } cy="50%" r="30" stroke-width="1" color="black" stroke="black" fill="#27ae60"/>
+        <text x={ this.boxWidth - 30 } y="50%" text-anchor="middle" dominant-baseline="middle" textLength="20%" lengthAdjust="spacingAndGlyphs">{ text }</text>
+      </svg>
+    );
+  }
+
+  createEndCircle(xPos, text) {
+    return (
+      <svg width={ this.boxWidth } height={ this.boxHeight } x={ xPos }>
+        <circle cx={ 30 } cy="50%" r="30" stroke-width="2" color="black" stroke="black" fill="#27ae60"/>
+        <text x={ 30 } y="50%" text-anchor="middle" dominant-baseline="middle" textLength="20%" lengthAdjust="spacingAndGlyphs">{ text }</text>
+      </svg>
+    );
+  }
+
+  createOneBox(xPos, policyId, loopElementModelId, name, title, policyType) {
+    return (
+      <svg width={ this.boxWidth } height={ this.boxHeight } x={ xPos } title="test">
+        <g policyId={ policyId } loopElementModelId={ loopElementModelId } policyType={ policyType }>
+          <rect width="100%" height="100%" stroke-width="2" color="black" stroke="black" fill="#1abc9c"/>
+          <text x="50%" y="15%" color="white" fill="white" dominant-baseline="middle" text-anchor="middle" textLength="50%" lengthAdjust="spacingAndGlyphs">{ title }</text>
+          <text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle" textLength="80%" lengthAdjust="spacingAndGlyphs">{ name }</text>
+          <text x="50%" y="80%" text-anchor="middle" dominant-baseline="middle" textLength="110%" lengthAdjust="spacingAndGlyphs">{ policyId }</text>
+        </g>
+      </svg>
+    );
+  }
+
+  createSvgFromTemplate() {
+    const allElements = [];
+    var xPos = 0;
+
+    allElements.push(this.createBeginCircle(xPos, "Start"))
+    xPos += (this.boxWidth + this.boxSpace);
+
+    allElements.push(this.createOneArrow(xPos - this.boxSpace));
+
+    allElements.push(this.createVesBox(xPos));
+    xPos += (this.boxWidth + this.boxSpace);
+
+    allElements.push(this.createOneArrow(xPos - this.boxSpace));
+    //createOneBox(xPos, policyId, loopElementModelId , name, title, policyType)
+    for (var loopElement of this.state.loopCache.getAllLoopElementModels()) {
+
+      allElements.push(this.createOneBox(xPos,
+        loopElement['name'],
+        loopElement['name'],
+        loopElement['shortName'],
+        loopElement['loopElementType'],
+        loopElement['loopElementType']))
+      xPos += (this.boxWidth + this.boxSpace);
+      allElements.push(this.createOneArrow(xPos - this.boxSpace));
     }
 
-	handleSvgClick(event) {
-		console.debug("svg click event received");
-		if (this.state.clickable) {
-			var elementName = event.target.parentNode.getAttribute('policyId');
-			console.info("SVG element clicked", elementName);
-			// Only allow movement to policy editing IF there busyLoadingCOunt is 0,
-			// meaning we are not waiting for refreshStatus to complete, for example
-			if (elementName !== null && !this.props.isBusyLoading()) {
-				this.props.history.push("/policyModal/"+event.target.parentNode.getAttribute('policyType')+"/"+elementName);
-			}
-		}
-	}
+    allElements.push(this.createEndCircle(xPos, "End"))
+    xPos += (this.boxWidth + this.boxSpace);
 
-    createVesBox (xPos) {
-        return this.createOneBox(xPos,null,null,'VES Collector','VES',null);
+    return allElements;
+  }
+
+  createSvgFromInstance() {
+    const allElements = [];
+    var xPos = 0;
+
+    allElements.push(this.createBeginCircle(xPos, "Start"))
+    xPos += (this.boxWidth + this.boxSpace);
+
+    allElements.push(this.createOneArrow(xPos - this.boxSpace));
+
+    allElements.push(this.createVesBox(xPos));
+    xPos += (this.boxWidth + this.boxSpace);
+
+    allElements.push(this.createOneArrow(xPos - this.boxSpace));
+
+    for (var msPolicy in this.state.loopCache.getMicroServicePolicies()) {
+      var loopElementModelName = this.state.loopCache.getMicroServicePolicies()[msPolicy]['loopElementModel'];
+      if (loopElementModelName !== undefined) {
+        loopElementModelName = loopElementModelName['name'];
+      }
+      allElements.push(this.createOneBox(xPos,
+        this.state.loopCache.getMicroServicePolicies()[msPolicy]['name'],
+        loopElementModelName,
+        this.state.loopCache.getMicroServicePolicies()[msPolicy]['policyModel']['policyAcronym'],
+        'microservice',
+        OnapConstant.microServiceType))
+      xPos += (this.boxWidth + this.boxSpace);
+      allElements.push(this.createOneArrow(xPos - this.boxSpace));
     }
 
-    createOneArrow(xPos) {
-        return (
-         <svg width={this.boxSpace} height={this.boxHeight} x={xPos}>
-           <defs>
-            		<marker viewBox="0 0 20 20" markerWidth="20" markerHeight="20" orient="auto" refX="8.5" refY="5" id="arrow">
-            			<path d="m 1 5 l 0 -3 l 7 3 l -7 3 z"
-            				stroke-width= "1" stroke-linecap= "butt" stroke-dasharray= "10000, 1"
-            				fill="#000000" stroke="#000000" />
-            		</marker>
-           </defs>
-           <line x1="0" y1="50%" x2="100%" y2="50%" stroke-width="2" color="black" stroke="black" marker-end="url(#arrow)"/>
-         </svg>
-        );
+    for (var opPolicy in this.state.loopCache.getOperationalPolicies()) {
+      loopElementModelName = this.state.loopCache.getOperationalPolicies()[opPolicy]['loopElementModel'];
+      if (loopElementModelName !== undefined) {
+        loopElementModelName = loopElementModelName['name'];
+      }
+      allElements.push(this.createOneBox(xPos,
+        this.state.loopCache.getOperationalPolicies()[opPolicy]['name'],
+        loopElementModelName,
+        this.state.loopCache.getOperationalPolicies()[opPolicy]['policyModel']['policyAcronym'],
+        'operational',
+        OnapConstant.operationalPolicyType))
+      xPos += (this.boxWidth + this.boxSpace);
+      allElements.push(this.createOneArrow(xPos - this.boxSpace));
     }
 
-    createBeginCircle(xPos, text) {
-            return (
-            <svg width={this.boxWidth} height={this.boxHeight} x={xPos}>
-                <circle cx={this.boxWidth-30} cy="50%" r="30" stroke-width="1" color="black" stroke="black" fill="#27ae60"/>
-                <text x={this.boxWidth-30} y="50%" text-anchor="middle" dominant-baseline="middle" textLength="20%" lengthAdjust="spacingAndGlyphs" >{text}</text>
-            </svg>
-            );
-    }
+    allElements.push(this.createEndCircle(xPos, "End"))
+    xPos += (this.boxWidth + this.boxSpace);
 
-    createEndCircle(xPos, text) {
-            return (
-            <svg width={this.boxWidth} height={this.boxHeight} x={xPos}>
-                <circle cx={30} cy="50%" r="30" stroke-width="2" color="black" stroke="black" fill="#27ae60"/>
-                <text x={30} y="50%" text-anchor="middle" dominant-baseline="middle" textLength="20%" lengthAdjust="spacingAndGlyphs" >{text}</text>
-            </svg>
-            );
-    }
+    return allElements;
+  }
 
-    createOneBox(xPos, policyId, loopElementModelId , name, title, policyType) {
-        return (
-        <svg width={this.boxWidth} height={this.boxHeight} x={xPos} title="test">
-            <g policyId={policyId} loopElementModelId={loopElementModelId} policyType={policyType}>
-                <rect width="100%" height="100%" stroke-width="2" color="black" stroke="black" fill="#1abc9c"/>
-                <text x="50%" y="15%" color="white" fill="white" dominant-baseline="middle" text-anchor="middle" textLength="50%" lengthAdjust="spacingAndGlyphs">{title}</text>
-                <text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle" textLength="80%" lengthAdjust="spacingAndGlyphs" >{name}</text>
-                <text x="50%" y="80%" text-anchor="middle" dominant-baseline="middle" textLength="110%" lengthAdjust="spacingAndGlyphs" >{policyId}</text>
-            </g>
+  renderSvg() {
+    if (this.state.loopCache.getLoopName() === undefined) {
+      return [emptySvg];
+    }
+    if (this.state.generatedFrom === SvgGenerator.GENERATED_FROM_INSTANCE) {
+      return this.createSvgFromInstance();
+    } else if (this.state.generatedFrom === SvgGenerator.GENERATED_FROM_TEMPLATE) {
+      return this.createSvgFromTemplate();
+    }
+  }
+
+  render() {
+    var allTheElements = this.renderSvg();
+    var svgWidth = this.boxWidth * allTheElements.length;
+    var svgHeight = this.boxHeight + 50;
+    return (
+
+      <DivStyled onClick={ this.handleSvgClick }>
+        <svg key="main" height={ svgHeight } width={ svgWidth } viewBox="0,0,{svgWidth},{svgHeight}" preserveAspectRatio="none">
+          <svg key="content" x="-50" y="25">
+            { allTheElements }
+          </svg>
         </svg>
-        );
-    }
-
-    createSvgFromTemplate() {
-        const allElements = [];
-        var xPos = 0;
-
-        allElements.push(this.createBeginCircle(xPos,"Start"))
-        xPos+=(this.boxWidth+this.boxSpace);
-
-        allElements.push(this.createOneArrow(xPos-this.boxSpace));
-
-        allElements.push(this.createVesBox(xPos));
-        xPos+=(this.boxWidth+this.boxSpace);
-
-        allElements.push(this.createOneArrow(xPos-this.boxSpace));
-        //createOneBox(xPos, policyId, loopElementModelId , name, title, policyType)
-        for (var loopElement of this.state.loopCache.getAllLoopElementModels()) {
-
-            allElements.push(this.createOneBox(xPos,
-                loopElement['name'],
-                loopElement['name'],
-                loopElement['shortName'],
-                loopElement['loopElementType'],
-                loopElement['loopElementType']))
-            xPos+=(this.boxWidth+this.boxSpace);
-            allElements.push(this.createOneArrow(xPos-this.boxSpace));
-        }
-
-        allElements.push(this.createEndCircle(xPos, "End"))
-        xPos+=(this.boxWidth+this.boxSpace);
-
-        return allElements;
-    }
-
-    createSvgFromInstance() {
-        const allElements = [];
-        var xPos = 0;
-
-        allElements.push(this.createBeginCircle(xPos,"Start"))
-        xPos+=(this.boxWidth+this.boxSpace);
-
-        allElements.push(this.createOneArrow(xPos-this.boxSpace));
-
-        allElements.push(this.createVesBox(xPos));
-        xPos+=(this.boxWidth+this.boxSpace);
-
-        allElements.push(this.createOneArrow(xPos-this.boxSpace));
-
-        for (var msPolicy in this.state.loopCache.getMicroServicePolicies()) {
-            var loopElementModelName =  this.state.loopCache.getMicroServicePolicies()[msPolicy]['loopElementModel'];
-            if (loopElementModelName !== undefined) {
-                loopElementModelName = loopElementModelName['name'];
-            }
-            allElements.push(this.createOneBox(xPos,
-                this.state.loopCache.getMicroServicePolicies()[msPolicy]['name'],
-                loopElementModelName,
-                this.state.loopCache.getMicroServicePolicies()[msPolicy]['policyModel']['policyAcronym'],
-                'microservice',
-                OnapConstant.microServiceType))
-            xPos+=(this.boxWidth+this.boxSpace);
-            allElements.push(this.createOneArrow(xPos-this.boxSpace));
-        }
-
-        for (var opPolicy in this.state.loopCache.getOperationalPolicies()) {
-            loopElementModelName =  this.state.loopCache.getOperationalPolicies()[opPolicy]['loopElementModel'];
-            if (loopElementModelName !== undefined) {
-                loopElementModelName = loopElementModelName['name'];
-            }
-            allElements.push(this.createOneBox(xPos,
-                this.state.loopCache.getOperationalPolicies()[opPolicy]['name'],
-                loopElementModelName,
-                this.state.loopCache.getOperationalPolicies()[opPolicy]['policyModel']['policyAcronym'],
-                'operational',
-                OnapConstant.operationalPolicyType))
-            xPos+=(this.boxWidth+this.boxSpace);
-            allElements.push(this.createOneArrow(xPos-this.boxSpace));
-        }
-
-        allElements.push(this.createEndCircle(xPos, "End"))
-        xPos+=(this.boxWidth+this.boxSpace);
-
-        return allElements;
-    }
-
-    renderSvg() {
-        if (this.state.loopCache.getLoopName() === undefined) {
-            return [emptySvg];
-        }
-        if (this.state.generatedFrom === SvgGenerator.GENERATED_FROM_INSTANCE) {
-            return this.createSvgFromInstance();
-        } else if (this.state.generatedFrom === SvgGenerator.GENERATED_FROM_TEMPLATE) {
-            return this.createSvgFromTemplate();
-        }
-    }
-
-    render() {
-        var allTheElements = this.renderSvg();
-        var svgWidth = this.boxWidth*allTheElements.length;
-        var svgHeight = this.boxHeight+50;
-        return (
-
-            <DivStyled onClick={this.handleSvgClick} >
-                <svg key="main" height={svgHeight} width={svgWidth}  viewBox="0,0,{svgWidth},{svgHeight}" preserveAspectRatio="none">
-                    <svg key="content" x="-50" y="25">
-                        {allTheElements}
-					</svg>
-                </svg>
-            </DivStyled>
-        );
-    }
+      </DivStyled>
+    );
+  }
 }
 
 export default withRouter(SvgGenerator);
