diff --git a/skyquake/framework/core/modules/routes/inactivity.js b/skyquake/framework/core/modules/routes/inactivity.js
index 7c3c440..a90258d 100644
--- a/skyquake/framework/core/modules/routes/inactivity.js
+++ b/skyquake/framework/core/modules/routes/inactivity.js
@@ -1,6 +1,6 @@
 
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/skyquake/plugins/composer/src/src/components/ConfigPrimitiveParameters/ConfigPrimitiveParameters.js b/skyquake/plugins/composer/src/src/components/ConfigPrimitiveParameters/ConfigPrimitiveParameters.js
index 3621061..848f0b4 100644
--- a/skyquake/plugins/composer/src/src/components/ConfigPrimitiveParameters/ConfigPrimitiveParameters.js
+++ b/skyquake/plugins/composer/src/src/components/ConfigPrimitiveParameters/ConfigPrimitiveParameters.js
@@ -49,7 +49,7 @@
 import imgConnection from '../../../../node_modules/open-iconic/svg/random.svg'
 import imgClassifier from '../../../../node_modules/open-iconic/svg/spreadsheet.svg'
 import imgReorder from '../../../../node_modules/open-iconic/svg/menu.svg'
-import EditDescriptorModelProperties from '../EditDescriptorModelProperties'
+import EditConfigParameterMap from '../EditConfigParameterMap'
 function configParameterMapMap(ap, i) {
 
     const context = this;
@@ -214,7 +214,7 @@
                     {
                         containers.map(function(c, i) {
                             if(c.className == 'ConfigParameterMap') {
-                                return <EditDescriptorModelProperties key={i} container={c} width={self.props.width} />
+                                return <EditConfigParameterMap key={i} container={c} width={self.props.width} />
                             }
                         })
                     }
diff --git a/skyquake/plugins/composer/src/src/components/EditConfigParameterMap.js b/skyquake/plugins/composer/src/src/components/EditConfigParameterMap.js
new file mode 100644
index 0000000..1add58c
--- /dev/null
+++ b/skyquake/plugins/composer/src/src/components/EditConfigParameterMap.js
@@ -0,0 +1,685 @@
+/*
+ *
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   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.
+ *
+ */
+/**
+ * Created by onvelocity on 1/18/16.
+ *
+ * This class generates the form fields used to edit the CONFD JSON model.
+ */
+'use strict';
+
+import _ from 'lodash'
+import utils from '../libraries/utils'
+import React from 'react'
+import ClassNames from 'classnames'
+import changeCase from 'change-case'
+import toggle from '../libraries/ToggleElementHandler'
+import Button from './Button'
+import Property from '../libraries/model/DescriptorModelMetaProperty'
+import ComposerAppActions from '../actions/ComposerAppActions'
+import CatalogItemsActions from '../actions/CatalogItemsActions'
+import DESCRIPTOR_MODEL_FIELDS from '../libraries/model/DescriptorModelFields'
+import DescriptorModelFactory from '../libraries/model/DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../libraries/model/DescriptorModelMetaFactory'
+import SelectionManager from '../libraries/SelectionManager'
+import DeletionManager from '../libraries/DeletionManager'
+import DescriptorModelIconFactory from '../libraries/model/IconFactory'
+import getEventPath from '../libraries/getEventPath'
+import CatalogDataStore from '../stores/CatalogDataStore'
+
+import imgAdd from '../../../node_modules/open-iconic/svg/plus.svg'
+import imgRemove from '../../../node_modules/open-iconic/svg/trash.svg'
+
+import '../styles/EditDescriptorModelProperties.scss'
+
+
+
+function getDescriptorMetaBasicForType(type) {
+	const basicPropertiesFilter = d => _.includes(DESCRIPTOR_MODEL_FIELDS[type], d.name);
+	return DescriptorModelMetaFactory.getModelMetaForType(type, basicPropertiesFilter) || {properties: []};
+}
+
+function getDescriptorMetaAdvancedForType(type) {
+	const advPropertiesFilter = d => !_.includes(DESCRIPTOR_MODEL_FIELDS[type], d.name);
+	return DescriptorModelMetaFactory.getModelMetaForType(type, advPropertiesFilter) || {properties: []};
+}
+
+function getTitle(model = {}) {
+	if (typeof model['short-name'] === 'string' && model['short-name']) {
+		return model['short-name'];
+	}
+	if (typeof model.name === 'string' && model.name) {
+		return model.name;
+	}
+	if (model.uiState && typeof model.uiState.displayName === 'string' && model.uiState.displayName) {
+		return model.uiState.displayName
+	}
+	if (typeof model.id === 'string') {
+		return model.id;
+	}
+}
+function startEditing() {
+		DeletionManager.removeEventListeners();
+	}
+
+	function endEditing() {
+		DeletionManager.addEventListeners();
+	}
+
+	function onClickSelectItem(property, path, value, event) {
+		event.preventDefault();
+		const root = this.getRoot();
+		if (SelectionManager.select(value)) {
+			CatalogItemsActions.catalogItemMetaDataChanged(root.model);
+		}
+	}
+
+	function onFocusPropertyFormInputElement(property, path, value, event) {
+
+		event.preventDefault();
+		startEditing();
+
+		function removeIsFocusedClass(event) {
+			event.target.removeEventListener('blur', removeIsFocusedClass);
+			Array.from(document.querySelectorAll('.-is-focused')).forEach(d => d.classList.remove('-is-focused'));
+		}
+
+		removeIsFocusedClass(event);
+
+		const propertyWrapper = getEventPath(event).reduce((parent, element) => {
+			if (parent) {
+				return parent;
+			}
+			if (!element.classList) {
+				return false;
+			}
+			if (element.classList.contains('property')) {
+				return element;
+			}
+		}, false);
+
+		if (propertyWrapper) {
+			propertyWrapper.classList.add('-is-focused');
+			event.target.addEventListener('blur', removeIsFocusedClass);
+		}
+
+	}
+
+	function buildAddPropertyAction(container, property, path) {
+		function onClickAddProperty(property, path, event) {
+			event.preventDefault();
+			//SelectionManager.resume();
+			const create = Property.getContainerCreateMethod(property, this);
+			if (create) {
+				const model = null;
+				create(model, path, property);
+			} else {
+				const name = path.join('.');
+				const value = Property.createModelInstance(property);
+				utils.assignPathValue(this.model, name, value);
+			}
+			CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
+		}
+		return (
+				<Button className="inline-hint" onClick={onClickAddProperty.bind(container, property, path)} label="Add" src={imgAdd} />
+		);
+	}
+
+	function buildRemovePropertyAction(container, property, path) {
+		function onClickRemoveProperty(property, path, event) {
+			event.preventDefault();
+			const name = path.join('.');
+			const removeMethod = Property.getContainerMethod(property, this, 'remove');
+			if (removeMethod) {
+				removeMethod(utils.resolvePath(this.model, name));
+			} else {
+				utils.removePathValue(this.model, name);
+			}
+			CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
+		}
+		return (
+			<Button className="remove-property-action inline-hint" title="Remove" onClick={onClickRemoveProperty.bind(container, property, path)} label="Remove" src={imgRemove}/>
+		);
+	}
+
+	function onFormFieldValueChanged(event) {
+		if (DescriptorModelFactory.isContainer(this)) {
+			event.preventDefault();
+			const name = event.target.name;
+			const value = event.target.value;
+			utils.assignPathValue(this.model, name, value);
+			CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
+		}
+	}
+
+	function buildField(container, property, path, value, fieldKey) {
+		let cds = CatalogDataStore;
+		let catalogs = cds.getTransientCatalogs();
+
+		const name = path.join('.');
+		const isEditable = true;
+		const isGuid = Property.isGuid(property);
+		const onChange = onFormFieldValueChanged.bind(container);
+		const isEnumeration = Property.isEnumeration(property);
+		const isLeafRef = Property.isLeafRef(property);
+		const onFocus = onFocusPropertyFormInputElement.bind(container, property, path, value);
+		const placeholder = changeCase.title(property.name);
+		const className = ClassNames(property.name + '-input', {'-is-guid': isGuid});
+		const fieldValue = value ? (value.constructor.name != "Object") ? value : '' : undefined;
+		if (isEnumeration) {
+			const enumeration = Property.getEnumeration(property, value);
+			const options = enumeration.map((d, i) => {
+				// note yangforge generates values for enums but the system does not use them
+				// so we categorically ignore them
+				// https://trello.com/c/uzEwVx6W/230-bug-enum-should-not-use-index-only-name
+				//return <option key={fieldKey + ':' + i} value={d.value}>{d.name}</option>;
+				return <option key={fieldKey.toString() + ':' + i} value={d.name}>{d.name}</option>;
+			});
+			const isValueSet = enumeration.filter(d => d.isSelected).length > 0;
+			if (!isValueSet || property.cardinality === '0..1') {
+				const noValueDisplayText = changeCase.title(property.name);
+				options.unshift(<option key={'(value-not-in-enum)' + fieldKey.toString()} value="" placeholder={placeholder}>{noValueDisplayText}</option>);
+			}
+			return <select key={fieldKey.toString()} id={fieldKey.toString()} className={ClassNames({'-value-not-set': !isValueSet})} name={name} value={value} title={name} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} readOnly={!isEditable}>{options}</select>;
+		}
+
+		if (isLeafRef) {
+			let fullFieldKey = _.isArray(fieldKey) ? fieldKey.join(':') : fieldKey;
+			let containerRef = container;
+			while (containerRef.parent) {
+				fullFieldKey = containerRef.parent.key + ':' + fullFieldKey;
+				containerRef = containerRef.parent;
+			}
+			const leafRefPathValues = Property.getLeafRef(property, path, value, fullFieldKey, catalogs, container);
+
+			const options = leafRefPathValues && leafRefPathValues.map((d, i) => {
+				return <option key={fieldKey.toString() + ':' + i} value={d.value}>{d.value}</option>;
+			});
+			const isValueSet = leafRefPathValues.filter(d => d.isSelected).length > 0;
+			if (!isValueSet || property.cardinality === '0..1') {
+				const noValueDisplayText = changeCase.title(property.name);
+				options.unshift(<option key={'(value-not-in-leafref)' + fieldKey.toString()} value="" placeholder={placeholder}>{noValueDisplayText}</option>);
+			}
+			return <select key={fieldKey.toString()} id={fieldKey.toString()} className={ClassNames({'-value-not-set': !isValueSet})} name={name} value={value} title={name} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} readOnly={!isEditable}>{options}</select>;
+		}
+
+		if (property['preserve-line-breaks']) {
+			return <textarea key={fieldKey.toString()} cols="5" id={fieldKey.toString()} name={name} value={value} placeholder={placeholder} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing} readOnly={!isEditable} />;
+		}
+
+		return <input key={fieldKey.toString()}
+					  id={fieldKey.toString()}
+					  type="text"
+					  name={name}
+					  value={fieldValue}
+					  className={className}
+					  placeholder={placeholder}
+					  onChange={onChange}
+					  onFocus={onFocus}
+					  onBlur={endEditing}
+					  onMouseDown={startEditing}
+					  onMouseOver={startEditing}
+					  onMouseOut={endEditing}
+					  onMouseLeave={endEditing}
+					  readOnly={!isEditable}
+		/>;
+
+	}
+
+	function buildElement(container, property, valuePath, value) {
+		return property.properties.map((property, index) => {
+			let childValue;
+			const childPath = valuePath.slice();
+			if (typeof value === 'object') {
+				childValue = value[property.name];
+			}
+			if(property.type != 'choice'){
+						childPath.push(property.name);
+			}
+			return build(container, property, childPath, childValue);
+
+		});
+	}
+
+    function buildChoice(container, property, path, value, key, props={}) {
+
+		function onFormFieldValueChanged(event) {
+			if (DescriptorModelFactory.isContainer(this)) {
+
+				event.preventDefault();
+
+				let name = event.target.name;
+				const value = event.target.value;
+
+
+				/*
+					Transient State is stored for convenience in the uiState field.
+					The choice yang type uses case elements to describe the "options".
+					A choice can only ever have one option selected which allows
+					the system to determine which type is selected by the name of
+					the element contained within the field.
+				 */
+				/*
+					const stateExample = {
+						uiState: {
+							choice: {
+								'conf-config': {
+									selected: 'rest',
+									'case': {
+										rest: {},
+										netconf: {},
+										script: {}
+									}
+								}
+							}
+						}
+					};
+				*/
+				const statePath = ['uiState.choice'].concat(name);
+				const stateObject = utils.resolvePath(this.model, statePath.join('.')) || {};
+				const selected = stateObject.selected ? stateObject.selected.split('.')[1] : undefined;
+				// write state back to the model so the new state objects are captured
+				utils.assignPathValue(this.model, statePath.join('.'), stateObject);
+
+				// write the current choice value into the state
+				let choiceObject = utils.resolvePath(this.model, [name, selected].join('.'));
+				let isTopCase = false;
+				if (!choiceObject) {
+					isTopCase = true;
+					choiceObject = utils.resolvePath(this.model, [selected].join('.'));
+				}
+				utils.assignPathValue(stateObject, [selected].join('.'), _.cloneDeep(choiceObject));
+
+				if(selected) {
+					if(this.model.uiState.choice.hasOwnProperty(name)) {
+						delete this.model[selected];
+						utils.removePathValue(this.model, [name, selected].join('.'), isTopCase);
+					} else {
+						// remove the current choice value from the model
+						utils.removePathValue(this.model, [name, selected].join('.'), isTopCase);
+					}
+				}
+
+				// get any state for the new selected choice
+				const newChoiceObject = utils.resolvePath(stateObject, [value].join('.')) || {};
+
+				// assign new choice value to the model
+				if (isTopCase) {
+					utils.assignPathValue(this.model, [name, value].join('.'), newChoiceObject);
+				} else {
+					utils.assignPathValue(this.model, [value].join('.'), newChoiceObject)
+				}
+
+
+				// update the selected name
+				utils.assignPathValue(this.model, statePath.concat('selected').join('.'), value);
+
+				CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
+			}
+		}
+
+		const caseByNameMap = {};
+
+		const onChange = onFormFieldValueChanged.bind(container);
+
+		const cases = property.properties.map(d => {
+			if (d.type === 'case') {
+				caseByNameMap[d.name] = d.properties[0];
+				return {
+					optionName: d.name,
+					optionTitle: d.description,
+					//represents case name and case element name
+					optionValue: [d.name, d.properties[0].name].join('.')
+				};
+			}
+			caseByNameMap[d.name] = d;
+			return {optionName: d.name};
+		});
+
+		const options = [{optionName: '', optionValue: false}].concat(cases).map((d, i) => {
+			return (
+				<option key={i} value={d.optionValue} title={d.optionTitle}>
+					{d.optionName}
+					{i ? null : changeCase.title(property.name)}
+				</option>
+			);
+		});
+
+		const selectName = path.join('.');
+		let selectedOptionPath = ['uiState.choice', selectName, 'selected'].join('.');
+		//Currently selected choice/case statement on UI model
+		let selectedOptionValue = utils.resolvePath(container.model, selectedOptionPath);
+		//If first time loaded, and none is selected, check if there is a value corresponding to a case statement in the container model
+		if(!selectedOptionValue) {
+			//get field properties for choice on container model
+			let fieldProperties = utils.resolvePath(container.model, selectName);
+			if(fieldProperties) {
+				//Check each case statement in model and see if it is present in container model.
+				cases.map(function(c){
+					if(fieldProperties.hasOwnProperty(c.optionValue.split('.')[1])) {
+						utils.assignPathValue(container.model, ['uiState.choice', selectName, 'selected'].join('.'), c.optionValue);
+					}
+				});
+				selectedOptionValue = utils.resolvePath(container.model, ['uiState.choice', selectName, 'selected'].join('.'));
+			} else {
+				property.properties.map(function(p) {
+					let pname = p.properties[0].name;
+					if(container.model.hasOwnProperty(pname)) {
+						utils.assignPathValue(container.model, ['uiState.choice', selectName, 'selected'].join('.'), [p.name, pname].join('.'));
+					}
+				})
+				selectedOptionValue = utils.resolvePath(container.model, ['uiState.choice', selectName, 'selected'].join('.'));
+			}
+		}
+		//If selectedOptionValue is present, take first item in string which represents the case name.
+		const valueProperty = caseByNameMap[selectedOptionValue ? selectedOptionValue.split('.')[0] : undefined] || {properties: []};
+		const isLeaf = Property.isLeaf(valueProperty);
+		const hasProperties = _.isArray(valueProperty.properties) && valueProperty.properties.length;
+		const isMissingDescriptorMeta = !hasProperties && !Property.isLeaf(valueProperty);
+		//Some magic that prevents errors for arising
+		const valueResponse = valueProperty.properties.length ? valueProperty.properties.map((d, i) => {
+			const childPath = path.concat(valueProperty.name, d.name);
+			const childValue = utils.resolvePath(container.model, childPath.join('.'));
+			return (
+				<div key={childPath.concat('info', i).join(':')}>
+					{build(container, d, childPath, childValue, props)}
+				</div>
+			);
+		}) : (!isMissingDescriptorMeta) ? build(container, valueProperty, path.concat(valueProperty.name), utils.resolvePath(container.model, path.concat(valueProperty.name).join('.')) || container.model[valueProperty.name]) : null
+		// end magic
+		const onFocus = onFocusPropertyFormInputElement.bind(container, property, path, value);
+
+		return (
+			<div key={key} className="choice">
+				<select key={Date.now()} className={ClassNames({'-value-not-set': !selectedOptionValue})} name={selectName} value={selectedOptionValue} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing}>
+					{options}
+				</select>
+				{valueResponse}
+			</div>
+		);
+
+	}
+
+	function buildSimpleListItem(container, property, path, value, key, index) {
+		// todo need to abstract this better
+		const title = getTitle(value);
+		var req = require.context("../", true, /\.svg/);
+		return (
+			<div>
+				<a href="#select-list-item" key={Date.now()} className={property.name + '-list-item simple-list-item '} onClick={onClickSelectItem.bind(container, property, path, value)}>
+					<img src={req('./' + DescriptorModelIconFactory.getUrlForType(property.name))} width="20px" />
+					<span>{title}</span>
+				</a>
+				{buildRemovePropertyAction(container, property, path)}
+			</div>
+		);
+	}
+
+	function buildRemoveListItem(container, property, valuePath, fieldKey, index) {
+		const className = ClassNames(property.name + '-remove actions');
+		return (
+			<div key={fieldKey.concat(index).join(':')} className={className}>
+				<h3>
+					<span className={property.type + '-name name'}>{changeCase.title(property.name)}</span>
+					<span className="info">{index + 1}</span>
+					{buildRemovePropertyAction(container, property, valuePath)}
+				</h3>
+			</div>
+		);
+	}
+
+	function buildLeafListItem(container, property, valuePath, value, key, index) {
+		// look at the type to determine how to parse the value
+		return (
+			<div>
+				{buildRemoveListItem(container, property, valuePath, key, index)}
+				{buildField(container, property, valuePath, value, key)}
+			</div>
+
+		);
+	}
+
+	function build(container, property, path, value, props = {}) {
+
+		const fields = [];
+		const isLeaf = Property.isLeaf(property);
+		const isArray = Property.isArray(property);
+		const isObject = Property.isObject(property);
+		const isLeafList = Property.isLeafList(property);
+		const fieldKey = [container.id].concat(path);
+		const isRequired = Property.isRequired(property);
+		const title = changeCase.titleCase(property.name);
+		const columnCount = property.properties.length || 1;
+		const isColumnar = isArray && (Math.round(props.width / columnCount) > 155);
+		const classNames = {'-is-required': isRequired, '-is-columnar': isColumnar};
+
+		if (!property.properties && isObject) {
+			const uiState = DescriptorModelMetaFactory.getModelMetaForType(property.name) || {};
+			property.properties = uiState.properties;
+		}
+
+		const hasProperties = _.isArray(property.properties) && property.properties.length;
+		const isMissingDescriptorMeta = !hasProperties && !Property.isLeaf(property);
+
+		// ensure value is not undefined for non-leaf property types
+		if (isObject) {
+			if (typeof value !== 'object') {
+				value = isArray ? [] : {};
+			}
+		}
+		const valueAsArray = _.isArray(value) ? value : isLeafList && typeof value === 'undefined' ? [] : [value];
+
+		const isMetaField = property.name === 'meta';
+		const isCVNFD = property.name === 'constituent-vnfd';
+		const isSimpleListView = Property.isSimpleList(property);
+
+		valueAsArray.forEach((value, index) => {
+
+			let field;
+			const key = fieldKey.slice();
+			const valuePath = path.slice();
+
+			if (isArray) {
+				valuePath.push(index);
+				key.push(index);
+			}
+
+			if (isMetaField) {
+				if (typeof value === 'object') {
+					value = JSON.stringify(value, undefined, 12);
+				} else if (typeof value !== 'string') {
+					value = '{}';
+				}
+			}
+
+			if (isMissingDescriptorMeta) {
+				field = <span key={key.concat('warning').join(':')} className="warning">No Descriptor Meta for {property.name}</span>;
+			} else if (property.type === 'choice') {
+                field = buildChoice(container, property, valuePath, value, key.join(':'), props);
+			} else if (isSimpleListView) {
+                field = buildSimpleListItem(container, property, valuePath, value, key, index, props);
+			} else if (isLeafList) {
+                field = buildLeafListItem(container, property, valuePath, value, key, index, props);
+			} else if (hasProperties) {
+                field = buildElement(container, property, valuePath, value, key.join(':'), props)
+			} else {
+                field = buildField(container, property, valuePath, value, key.join(':'), props);
+			}
+
+			function onClickLeaf(property, path, value, event) {
+				if (event.isDefaultPrevented()) {
+					return;
+				}
+				event.preventDefault();
+				event.stopPropagation();
+				this.getRoot().uiState.focusedPropertyPath = path.join('.');
+				console.log('property selected', path.join('.'));
+				ComposerAppActions.propertySelected([path.join('.')]);
+			}
+
+			const clickHandler = isLeaf ? onClickLeaf : () => {};
+			const isContainerList = isArray && !(isSimpleListView || isLeafList);
+
+			fields.push(
+				<div key={fieldKey.concat(['property-content', index]).join(':')}
+					 className={ClassNames('property-content', {'simple-list': isSimpleListView})}
+					 onClick={clickHandler.bind(container, property, valuePath, value)}>
+					{isContainerList ? buildRemoveListItem(container, property, valuePath, fieldKey, index) : null}
+					{field}
+				</div>
+			);
+
+		});
+
+		classNames['-is-leaf'] = isLeaf;
+		classNames['-is-array'] = isArray;
+		classNames['cols-' + columnCount] = isColumnar;
+
+		if (property.type === 'choice') {
+			value = utils.resolvePath(container.model, ['uiState.choice'].concat(path, 'selected').join('.'));
+			if(!value) {
+				property.properties.map(function(p) {
+					let pname = p.properties[0].name;
+					if(container.model.hasOwnProperty(pname)) {
+						value = container.model[pname];
+					}
+				})
+			}
+		}
+
+		let displayValue = typeof value === 'object' ? '' : value;
+		const displayValueInfo = isArray ? valueAsArray.filter(d => typeof d !== 'undefined').length + ' items' : '';
+
+		const onFocus = isLeaf ? event => event.target.classList.add('-is-focused') : false;
+
+		return (
+			<div key={fieldKey.join(':')} className={ClassNames(property.type + '-property property', classNames)} onFocus={onFocus}>
+				<h3 className="property-label">
+					<label htmlFor={fieldKey.join(':')}>
+						<span className={property.type + '-name name'}>{title}</span>
+						<small>
+							<span className={property.type + '-info info'}>{displayValueInfo}</span>
+							<span className={property.type + '-value value'}>{displayValue}</span>
+						</small>
+						{isArray ? buildAddPropertyAction(container, property, path.concat(valueAsArray.length)) : null}
+					</label>
+				</h3>
+				<span className={property.type + '-description description'}>{property.description}</span>
+				<val className="property-value">
+					{isCVNFD ? <span className={property.type + '-tip tip'}>Drag a VNFD from the Catalog to add more.</span> : null}
+					{fields}
+				</val>
+			</div>
+		);
+
+	}
+export default function EditDescriptorModelProperties(props, type) {
+
+    const container = props.container;
+
+    if (!(DescriptorModelFactory.isContainer(container))) {
+        return
+    }
+
+
+
+    const containerType = (_.isEmpty(type) ? false : type)|| container.uiState['qualified-type'] || container.uiState.type;
+	const basicProperties = getDescriptorMetaBasicForType(containerType).properties;
+
+
+	function buildAdvancedGroup() {
+		const properties = getDescriptorMetaAdvancedForType(containerType).properties;
+		if (properties.length === 0) {
+			return null;
+		}
+		const hasBasicFields = basicProperties.length > 0;
+		const closeGroup = basicProperties.length > 0;
+		return (
+			<div className="advanced-properties-group">
+
+				<div className="toggleable">
+					{properties.map((property,i) => {
+						const path = [property.name];
+						const value = container.model[property.name];
+						if(path == 'id') {
+							return null
+						}
+						if(path == 'config-parameter-request') {
+							return (
+								<div className="container-property property" key={path + '-' + i}>
+									<h3 className="property-label">
+										<span className="container-name name">{`VNF Index: ${value['member-vnf-index-ref']}`}</span>
+									</h3>
+									<val className="property-value">
+										<div className="property-content">
+											<val className="property-value" style={{width: '100%'}}>
+												<div className="property-content">
+													<div className="leaf-property property -is-leaf">
+														<h3 className="property-label">
+															<label for={path + '-' + i}>
+																<span className="leaf-name name">
+																	Parameter Request
+																</span>
+															</label>
+														</h3>
+														<input value={value['config-parameter-request-ref']} readonly placeholder="Parameter Request" name={path + '-' + i}>
+
+														</input>
+													</div>
+												</div>
+											</val>
+										</div>
+									</val>
+
+								</div>
+							)
+						} else {
+							return build(container, property, path, value, _.assign({toggle: true, width: props.width}, props));
+						}
+
+					})}
+				</div>
+				<div className="toggle-bottom-spacer" style={{visibility: 'hidden', 'height': '50%', position: 'absolute'}}>We need this so when the user closes the panel it won't shift away and scare the bj out of them!</div>
+			</div>
+		);
+	}
+
+	function buildMoreLess(d, i) {
+		return (
+			<span key={'bread-crumb-part-' + i}>
+				<a href="#select-item" onClick={onClickSelectItem.bind(d, null, null, d)}>{d.title}</a>
+				<i> / </i>
+			</span>
+		);
+	}
+
+	const path = [];
+	if (container.parent) {
+		path.push(container.parent);
+	}
+	path.push(container);
+
+	return (
+		<div className="EditDescriptorModelProperties -is-tree-view">
+			{buildAdvancedGroup()}
+		</div>
+	);
+
+}
+export {build}
+// export buildElement;
+// export buildChoice;
diff --git a/skyquake/plugins/composer/src/src/styles/CanvasPanelTray.scss b/skyquake/plugins/composer/src/src/styles/CanvasPanelTray.scss
index 55844b6..899eb8f 100644
--- a/skyquake/plugins/composer/src/src/styles/CanvasPanelTray.scss
+++ b/skyquake/plugins/composer/src/src/styles/CanvasPanelTray.scss
@@ -30,7 +30,7 @@
 	height: 25px;
 	min-width: 300px;
 	/* background-color: white;*/
-	background: #cbd1d1;
+	background: $panel-bg-color;
 	&.-with-transitions {
 		transition: height 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000);
 	}
@@ -65,14 +65,17 @@
 	&-buttons {
 		display: -ms-flexbox;
 		display: flex;
-		margin-top: 1px;
+		margin-top: 2px;
+		button {
+			padding: 6px 34px;
+		}
 	}
 	.tray-body {
 		top:31px;
 	}
 	.ConfigParameterMap {
 
-		background: #cbd1d1;
+		background: $panel-bg-color;
 
 		.EditDescriptorModelProperties {
 		    margin-left: 8px;
@@ -83,6 +86,8 @@
 			display:flex;
 			-ms-flex-wrap: wrap;
 			    flex-wrap: wrap;
+		    background: $panel-bg-color-contrast;
+		    margin:8px 0;
 		 	& > .leaf-property {
 			    -ms-flex: 1 0 100%;
 		        flex: 1 0 100%;
