Add new code new version

Change-Id: Ic02a76313503b526f17c3df29eb387a29fe6a42a
Signed-off-by: Michael Lando <ml636r@att.com>
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
new file mode 100644
index 0000000..d39b2af
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
@@ -0,0 +1,188 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import LicenseModelActionHelper from './licenseModel/LicenseModelActionHelper.js';
+import LicenseAgreementActionHelper from './licenseModel/licenseAgreement/LicenseAgreementActionHelper.js';
+import FeatureGroupsActionHelper from './licenseModel/featureGroups/FeatureGroupsActionHelper.js';
+import LicenseKeyGroupsActionHelper from './licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js';
+import EntitlementPoolsActionHelper from './licenseModel/entitlementPools/EntitlementPoolsActionHelper.js';
+import SoftwareProductActionHelper from './softwareProduct/SoftwareProductActionHelper.js';
+import SoftwareProductProcessesActionHelper from './softwareProduct/processes/SoftwareProductProcessesActionHelper.js';
+import SoftwareProductNetworksActionHelper from './softwareProduct/networks/SoftwareProductNetworksActionHelper.js';
+import SoftwareProductComponentsActionHelper from './softwareProduct/components/SoftwareProductComponentsActionHelper.js';
+import SoftwareProductComponentProcessesActionHelper from './softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js';
+import SoftwareProductComponentsNetworkActionHelper from './softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js';
+import SoftwareProductComponentsMonitoringAction from './softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js';
+import {actionTypes, enums} from './OnboardingConstants.js';
+import {navigationItems as SoftwareProductNavigationItems, actionTypes as SoftwareProductActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+import store from 'sdc-app/AppStore.js';
+
+function setCurrentScreen(dispatch, screen, props = {}) {
+	dispatch({
+		type: actionTypes.SET_CURRENT_SCREEN,
+		currentScreen: {
+			screen,
+			props
+		}
+	});
+}
+
+function  getCurrentLicenseModelVersion(licenseModelId) {
+	return store.getState().licenseModelList.find(({id}) => id === licenseModelId).version;
+}
+
+export default {
+
+	navigateToOnboardingCatalog(dispatch) {
+		LicenseModelActionHelper.fetchLicenseModels(dispatch);
+		SoftwareProductActionHelper.fetchSoftwareProductList(dispatch);
+		setCurrentScreen(dispatch, enums.SCREEN.ONBOARDING_CATALOG);
+	},
+
+	navigateToLicenseAgreements(dispatch, {licenseModelId, version}) {
+		if(!version) {
+			version = getCurrentLicenseModelVersion(licenseModelId);
+		}
+		LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version});
+		LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
+			setCurrentScreen(dispatch, enums.SCREEN.LICENSE_AGREEMENTS, {licenseModelId});
+		});
+	},
+
+	navigateToFeatureGroups(dispatch, {licenseModelId, version}) {
+		if(!version) {
+			version = getCurrentLicenseModelVersion(licenseModelId);
+		}
+		FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version});
+		setCurrentScreen(dispatch, enums.SCREEN.FEATURE_GROUPS, {licenseModelId});
+	},
+
+	navigateToEntitlementPools(dispatch, {licenseModelId, version}) {
+		if(!version) {
+			version = getCurrentLicenseModelVersion(licenseModelId);
+		}
+		EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version});
+		setCurrentScreen(dispatch, enums.SCREEN.ENTITLEMENT_POOLS, {licenseModelId});
+	},
+
+	navigateToLicenseKeyGroups(dispatch, {licenseModelId, version}) {
+		if(!version) {
+			version = getCurrentLicenseModelVersion(licenseModelId);
+		}
+		LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version});
+		setCurrentScreen(dispatch, enums.SCREEN.LICENSE_KEY_GROUPS, {licenseModelId});
+	},
+
+	navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, version, licensingVersion}) {
+		SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}).then(response => {
+			if(!licensingVersion) {
+				licensingVersion = response[0].licensingVersion;
+			}
+			if (!licenseModelId) {
+				licenseModelId = response[0].vendorId;
+			}
+
+			SoftwareProductActionHelper.loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion});
+			SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version});
+
+			setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, {softwareProductId, licenseModelId, version});
+		});
+	},
+
+	navigateToSoftwareProductDetails(dispatch, {softwareProductId}) {
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, {softwareProductId});
+	},
+
+	navigateToSoftwareProductAttachments(dispatch, {softwareProductId}) {
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS, {softwareProductId});
+	},
+
+	navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version}) {
+		if (softwareProductId) {
+			SoftwareProductProcessesActionHelper.fetchProcessesList(dispatch, {softwareProductId, version});
+		}
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES, {softwareProductId});
+	},
+
+	navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version}) {
+		if (softwareProductId) {
+			SoftwareProductNetworksActionHelper.fetchNetworksList(dispatch, {softwareProductId, version});
+		}
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS, {softwareProductId});
+	},
+
+	navigateToSoftwareProductComponents(dispatch, {softwareProductId}) {
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS, {softwareProductId});
+	},
+
+	navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId, version}) {
+		if (componentId && softwareProductId) {
+			SoftwareProductComponentProcessesActionHelper.fetchProcessesList(dispatch, {componentId, softwareProductId, version});
+		}
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES, {softwareProductId, componentId});
+	},
+
+	navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId}){
+		if (componentId && softwareProductId) {
+			SoftwareProductComponentsMonitoringAction.fetchExistingFiles(dispatch, {componentId, softwareProductId});
+		}
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING, {softwareProductId, componentId});
+	},
+
+	navigateToComponentStorage(dispatch, {softwareProductId, componentId}) {
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE, {softwareProductId, componentId});
+	},
+
+	navigateToComponentCompute(dispatch, {softwareProductId, componentId}) {
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE, {softwareProductId, componentId});
+	},
+
+	navigateToComponentNetwork(dispatch, {softwareProductId, componentId, version}) {
+		SoftwareProductComponentsNetworkActionHelper.fetchNICsList(dispatch, {softwareProductId, componentId, version});
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK, {softwareProductId, componentId});
+	},
+
+	navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId, version}) {
+		if (componentId && softwareProductId) {
+			SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId: componentId, version});
+			SoftwareProductComponentsActionHelper.fetchSoftwareProductComponentQuestionnaire(dispatch, {
+				softwareProductId,
+				vspComponentId: componentId,
+				version
+			});
+		}
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL, {softwareProductId, componentId});
+	},
+
+	navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version}) {
+		this.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId, version});
+		dispatch({
+			type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM,
+			mapOfExpandedIds: {
+				[SoftwareProductNavigationItems.COMPONENTS]: true,
+				[SoftwareProductNavigationItems.COMPONENTS + '|' + componentId]: true
+			}
+		});
+	},
+
+	navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId}) {
+		setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING, {softwareProductId, componentId});
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalog.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalog.js
new file mode 100644
index 0000000..4772c8d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalog.js
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import {default as OnboardingCatalogView, catalogItemTypes} from './OnboardingCatalogView.jsx';
+import OnboardingActionHelper from './OnboardingActionHelper.js';
+import LicenseModelCreationActionHelper from './licenseModel/creation/LicenseModelCreationActionHelper.js';
+import SoftwareProductCreationActionHelper from './softwareProduct/creation/SoftwareProductCreationActionHelper.js';
+
+
+const mapStateToProps = ({licenseModelList, softwareProductList, softwareProduct: {softwareProductCreation}, licenseModel: {licenseModelCreation}}) => {
+
+	let modalToShow;
+
+	if(licenseModelCreation.data) {
+		modalToShow = catalogItemTypes.LICENSE_MODEL;
+	} else if(softwareProductCreation.showModal && softwareProductCreation.data) {
+		modalToShow = catalogItemTypes.SOFTWARE_PRODUCT;
+	}
+
+	return {
+		licenseModelList,
+		softwareProductList,
+		modalToShow
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onSelectLicenseModel({id: licenseModelId}) {
+			OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId});
+		},
+		onSelectSoftwareProduct(softwareProduct) {
+			let {id: softwareProductId, vendorId: licenseModelId, licensingVersion} = softwareProduct;
+			OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, licensingVersion});
+		},
+		onAddSoftwareProductClick: () => SoftwareProductCreationActionHelper.open(dispatch),
+		onAddLicenseModelClick: () => LicenseModelCreationActionHelper.open(dispatch)
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(OnboardingCatalogView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalogView.jsx
new file mode 100644
index 0000000..f2a9db1
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalogView.jsx
@@ -0,0 +1,147 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+import objectValues from 'lodash/values.js';
+import LicenseModelCreation from './licenseModel/creation/LicenseModelCreation.js';
+import SoftwareProductCreation from './softwareProduct/creation/SoftwareProductCreation.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import classnames from 'classnames';
+import ExpandableInput from 'nfvo-components/input/ExpandableInput.jsx';
+
+export const catalogItemTypes = Object.freeze({
+	LICENSE_MODEL: 'license-model',
+	SOFTWARE_PRODUCT: 'software-product'
+});
+
+const catalogItemTypeClasses = {
+	LICENSE_MODEL: 'license-model-type',
+	SOFTWARE_PRODUCT: 'software-product-type'
+};
+
+class OnboardingCatalogView extends React.Component {
+
+	constructor(props) {
+		super(props);
+		this.state = {searchValue: ''};
+		this.handleSearch = this.handleSearch.bind(this);
+	}
+
+	handleSearch(event){
+		this.setState({searchValue: event.target.value});
+	}
+
+	static propTypes = {
+		licenseModelList: React.PropTypes.array,
+		softwareProductList: React.PropTypes.array,
+		modalToShow: React.PropTypes.oneOf(objectValues(catalogItemTypes)),
+		onSelectLicenseModel: React.PropTypes.func.isRequired,
+		onSelectSoftwareProduct: React.PropTypes.func.isRequired,
+		onAddLicenseModelClick: React.PropTypes.func.isRequired,
+		onAddSoftwareProductClick: React.PropTypes.func.isRequired
+	};
+
+	getModalDetails() {
+		const {modalToShow} = this.props;
+		switch (modalToShow) {
+			case catalogItemTypes.LICENSE_MODEL:
+				return {
+					title: i18n('New License Model'),
+					element: <LicenseModelCreation/>
+				};
+			case catalogItemTypes.SOFTWARE_PRODUCT:
+				return {
+					title: i18n('New Software Product'),
+					element: <SoftwareProductCreation/>
+				};
+		}
+	}
+
+	render() {
+		const modalDetails = this.getModalDetails();
+		const {licenseModelList, softwareProductList, onSelectLicenseModel, onSelectSoftwareProduct, onAddLicenseModelClick, onAddSoftwareProductClick, modalToShow} = this.props;
+
+		return (
+			<div className='catalog-view'>
+				<div className='catalog-header'>
+					<div className='catalog-header-title'>{i18n('Onboarding Catalog')}</div>
+					<ExpandableInput
+						onChange={this.handleSearch}
+						iconType='search'/>
+				</div>
+				<div className='catalog-list'>
+
+					<div className='create-catalog-item tile'>
+						<div className='plus-section'>
+							<div className='plus-icon-button'/>
+							<span>{i18n('ADD')}</span>
+						</div>
+						<div className='primary-btn new-license-model'>
+							<span
+								className='primary-btn-text'
+								onClick={() => onAddLicenseModelClick()}>{i18n('New License Model')}</span></div>
+						<div className='primary-btn'>
+							<span
+								className='primary-btn-text'
+								onClick={() => onAddSoftwareProductClick()}>{i18n('New Vendor Software Product')}</span>
+						</div>
+					</div>
+					{licenseModelList.filter(vlm => vlm.vendorName.toLowerCase().indexOf(this.state.searchValue.toLowerCase()) > -1).map(licenseModel => this.renderTile(
+						{
+							...licenseModel,
+							name: licenseModel.vendorName
+						},
+						catalogItemTypeClasses.LICENSE_MODEL,
+						() => onSelectLicenseModel(licenseModel))
+					)}
+					{softwareProductList.filter(vsp => vsp.name.toLowerCase().indexOf(this.state.searchValue.toLowerCase()) > -1).map(softwareProduct => this.renderTile(softwareProduct,
+						catalogItemTypeClasses.SOFTWARE_PRODUCT,
+						() => onSelectSoftwareProduct(softwareProduct))
+					)}
+				</div>
+				<Modal
+					show={Boolean(modalDetails)}
+					className={`${this.getCatalogItemTypeClassByItemType(modalToShow)}-modal`}>
+					<Modal.Header>
+						<Modal.Title>{modalDetails && modalDetails.title}</Modal.Title>
+					</Modal.Header>
+					<Modal.Body>
+						{
+							modalDetails && modalDetails.element
+						}
+					</Modal.Body>
+				</Modal>
+			</div>
+		);
+
+	}
+
+	getCatalogItemTypeClassByItemType(catalogItemType) {
+		switch (catalogItemType) {
+			case catalogItemTypes.LICENSE_MODEL:
+				return catalogItemTypeClasses.LICENSE_MODEL;
+			case catalogItemTypes.SOFTWARE_PRODUCT:
+				return catalogItemTypeClasses.SOFTWARE_PRODUCT;
+		}
+	}
+
+	renderTile(catalogItemData, catalogItemTypeClass, onSelect) {
+		let {status: itemStatus} = VersionControllerUtils.getCheckOutStatusKindByUserID(catalogItemData.status, catalogItemData.lockingUser);
+		return (
+			<div className='catalog-tile tile' key={catalogItemData.id} onClick={() => onSelect()}>
+				<div className={`catalog-tile-type ${catalogItemTypeClass}`}/>
+				<div className='catalog-tile-icon'>
+					<div className={`icon ${catalogItemTypeClass}-icon`}></div>
+				</div>
+				<div className='catalog-tile-content'>
+					<div className='catalog-tile-item-details'>
+						<div className='catalog-tile-item-name'>{catalogItemData.name}</div>
+						<div className='catalog-tile-item-version'>V {catalogItemData.version}</div>
+					</div>
+					<div className={classnames('catalog-tile-check-in-status', {'sprite-new checkout-editable-status-icon': itemStatus === 'Locked'})}>
+					</div>
+				</div>
+			</div>
+		);
+	}
+}
+export default OnboardingCatalogView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js
new file mode 100644
index 0000000..d9c177f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	SET_CURRENT_SCREEN: null,
+	SET_CURRENT_LICENSE_MODEL: null
+});
+
+export const enums = keyMirror({
+
+	BREADCRUMS: {
+		LICENSE_MODEL: 'LICENSE_MODEL',
+		LICENSE_AGREEMENTS: 'LICENSE_AGREEMENTS',
+		FEATURE_GROUPS: 'FEATURE_GROUPS',
+		ENTITLEMENT_POOLS: 'ENTITLEMENT_POOLS',
+		LICENSE_KEY_GROUPS: 'LICENSE_KEY_GROUPS',
+
+		SOFTWARE_PRODUCT: 'SOFTWARE_PRODUCT',
+		SOFTWARE_PRODUCT_DETAILS: 'SOFTWARE_PRODUCT_DETAILS',
+		SOFTWARE_PRODUCT_ATTACHMENTS: 'SOFTWARE_PRODUCT_ATTACHMENTS',
+		SOFTWARE_PRODUCT_PROCESSES: 'SOFTWARE_PRODUCT_PROCESSES',
+		SOFTWARE_PRODUCT_NETWORKS: 'SOFTWARE_PRODUCT_NETWORKS',
+		SOFTWARE_PRODUCT_COMPONENTS: 'SOFTWARE_PRODUCT_COMPONENTS',
+		SOFTWARE_PRODUCT_COMPONENT_PROCESSES: 'SOFTWARE_PRODUCT_COMPONENT_PROCESSES',
+		SOFTWARE_PRODUCT_COMPONENT_STORAGE: 'SOFTWARE_PRODUCT_COMPONENT_STORAGE',
+		SOFTWARE_PRODUCT_COMPONENT_GENERAL: 'SOFTWARE_PRODUCT_COMPONENT_GENERAL',
+		SOFTWARE_PRODUCT_COMPONENT_COMPUTE: 'SOFTWARE_PRODUCT_COMPONENT_COMPUTE',
+		SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: 'SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING',
+		SOFTWARE_PRODUCT_COMPONENT_MONITORING: 'SOFTWARE_PRODUCT_COMPONENT_MONITORING'
+	},
+
+	SCREEN: {
+		ONBOARDING_CATALOG: null,
+		LICENSE_AGREEMENTS: null,
+		FEATURE_GROUPS: null,
+		ENTITLEMENT_POOLS: null,
+		LICENSE_KEY_GROUPS: null,
+
+		SOFTWARE_PRODUCT_LANDING_PAGE: null,
+		SOFTWARE_PRODUCT_DETAILS: null,
+		SOFTWARE_PRODUCT_ATTACHMENTS: null,
+		SOFTWARE_PRODUCT_PROCESSES: null,
+		SOFTWARE_PRODUCT_NETWORKS: null,
+		SOFTWARE_PRODUCT_COMPONENTS: null,
+		SOFTWARE_PRODUCT_COMPONENT_PROCESSES: null,
+		SOFTWARE_PRODUCT_COMPONENT_COMPUTE: null,
+		SOFTWARE_PRODUCT_COMPONENT_STORAGE: null,
+		SOFTWARE_PRODUCT_COMPONENT_NETWORK: null,
+		SOFTWARE_PRODUCT_COMPONENT_GENERAL: null,
+		SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: null,
+		SOFTWARE_PRODUCT_COMPONENT_MONITORING: null
+	}
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
new file mode 100644
index 0000000..c4627b1
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
@@ -0,0 +1,501 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import {connect} from 'react-redux';
+import isEqual from 'lodash/isEqual.js';
+import objectValues from 'lodash/values.js';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Application from 'sdc-app/Application.jsx';
+import store from 'sdc-app/AppStore.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+
+import OnboardingCatalog from './OnboardingCatalog.js';
+import LicenseModel from './licenseModel/LicenseModel.js';
+import LicenseAgreementListEditor from './licenseModel/licenseAgreement/LicenseAgreementListEditor.js';
+import FeatureGroupListEditor from './licenseModel/featureGroups/FeatureGroupListEditor.js';
+import LicenseKeyGroupsListEditor from './licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js';
+import EntitlementPoolsListEditor from './licenseModel/entitlementPools/EntitlementPoolsListEditor.js';
+import SoftwareProduct from './softwareProduct/SoftwareProduct.js';
+import SoftwareProductLandingPage  from './softwareProduct/landingPage/SoftwareProductLandingPage.js';
+import SoftwareProductDetails  from './softwareProduct/details/SoftwareProductDetails.js';
+import SoftwareProductAttachments from './softwareProduct/attachments/SoftwareProductAttachments.js';
+import SoftwareProductProcesses from './softwareProduct/processes/SoftwareProductProcesses.js';
+import SoftwareProductNetworks from './softwareProduct/networks/SoftwareProductNetworks.js';
+import SoftwareProductComponentsList from './softwareProduct/components/SoftwareProductComponentsList.js';
+import SoftwareProductComponentProcessesList from './softwareProduct/components/processes/SoftwareProductComponentProcessesList.js';
+import SoftwareProductComponentStorage from './softwareProduct/components/storage/SoftwareProductComponentStorage.js';
+import SoftwareProductComponentsNetworkList from './softwareProduct/components/network/SoftwareProductComponentsNetworkList.js';
+import SoftwareProductComponentsGeneral from './softwareProduct/components/general/SoftwareProductComponentsGeneral.js';
+import SoftwareProductComponentsCompute from './softwareProduct/components/compute/SoftwareProductComponentCompute.js';
+import SoftwareProductComponentLoadBalancing from './softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js';
+import SoftwareProductComponentsMonitoring from './softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js';
+import {navigationItems as SoftwareProductNavigationItems, actionTypes as SoftwareProductActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+
+import {enums} from './OnboardingConstants.js';
+import OnboardingActionHelper from './OnboardingActionHelper.js';
+
+
+class OnboardingView extends React.Component {
+	static propTypes = {
+		currentScreen: React.PropTypes.shape({
+			screen: React.PropTypes.oneOf(objectValues(enums.SCREEN)).isRequired,
+			props: React.PropTypes.object.isRequired
+		}).isRequired
+	};
+
+	componentDidMount() {
+		let element = ReactDOM.findDOMNode(this);
+		element.addEventListener('click', event => {
+			if (event.target.tagName === 'A') {
+				event.preventDefault();
+			}
+		});
+		['wheel', 'mousewheel', 'DOMMouseScroll'].forEach(eventType =>
+			element.addEventListener(eventType, event => event.stopPropagation())
+		);
+	}
+
+	render() {
+		let {currentScreen} = this.props;
+		let {screen, props} = currentScreen;
+
+		return (
+			<div className='dox-ui dox-ui-punch-out dox-ui-punch-out-full-page'>
+				{(() => {
+					switch (screen) {
+						case enums.SCREEN.ONBOARDING_CATALOG:
+							return <OnboardingCatalog {...props}/>;
+
+						case enums.SCREEN.LICENSE_AGREEMENTS:
+						case enums.SCREEN.FEATURE_GROUPS:
+						case enums.SCREEN.ENTITLEMENT_POOLS:
+						case enums.SCREEN.LICENSE_KEY_GROUPS:
+							return (
+								<LicenseModel currentScreen={currentScreen}>
+								{
+									(()=>{
+										switch(screen) {
+											case enums.SCREEN.LICENSE_AGREEMENTS:
+												return <LicenseAgreementListEditor {...props}/>;
+											case enums.SCREEN.FEATURE_GROUPS:
+												return <FeatureGroupListEditor {...props}/>;
+											case enums.SCREEN.ENTITLEMENT_POOLS:
+												return <EntitlementPoolsListEditor {...props}/>;
+											case enums.SCREEN.LICENSE_KEY_GROUPS:
+												return <LicenseKeyGroupsListEditor {...props}/>;
+										}
+									})()
+								}
+								</LicenseModel>
+							);
+
+						case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE:
+						case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS:
+						case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
+						case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
+						case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
+						case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
+						case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
+						case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
+						case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
+						case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
+						case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
+						case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
+						case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
+							return (
+								<SoftwareProduct currentScreen={currentScreen}>
+								{
+									(()=>{
+										switch(screen) {
+											case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE:
+												return <SoftwareProductLandingPage {...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS:
+												return <SoftwareProductDetails {...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
+												return <SoftwareProductAttachments className='no-padding-content-area'  {...props} />;
+											case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
+												return <SoftwareProductProcesses {...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
+												return <SoftwareProductNetworks {...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
+												return <SoftwareProductComponentsList  {...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
+												return <SoftwareProductComponentProcessesList  {...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
+												return <SoftwareProductComponentStorage {...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
+												return <SoftwareProductComponentsNetworkList {...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
+												return <SoftwareProductComponentsGeneral{...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
+												return <SoftwareProductComponentsCompute {...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
+												return <SoftwareProductComponentLoadBalancing{...props}/>;
+											case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
+												return <SoftwareProductComponentsMonitoring {...props}/>;
+										}
+									})()
+								}
+								</SoftwareProduct>
+							);
+					}
+				})()}
+			</div>
+		);
+	}
+}
+const mapStateToProps = ({currentScreen}) => ({currentScreen});
+let Onboarding = connect(mapStateToProps, null)(OnboardingView);
+
+export default class OnboardingPunchOut {
+
+	render({options: {data, apiRoot, apiHeaders}, onEvent}, element) {
+		if (!this.unsubscribeFromStore) {
+			this.unsubscribeFromStore = store.subscribe(() => this.handleStoreChange());
+		}
+
+		if (!this.isConfigSet) {
+			Configuration.setATTApiRoot(apiRoot);
+			Configuration.setATTApiHeaders(apiHeaders);
+			this.isConfigSet = true;
+		}
+
+		this.onEvent = (...args) => onEvent(...args);
+		this.handleData(data);
+
+		if (!this.rendered) {
+			ReactDOM.render(
+				<Application>
+					<Onboarding/>
+				</Application>,
+				element
+			);
+			this.rendered = true;
+		}
+	}
+
+	unmount(element) {
+		ReactDOM.unmountComponentAtNode(element);
+		this.rendered = false;
+		this.unsubscribeFromStore();
+		this.unsubscribeFromStore = null;
+	}
+
+	handleData(data) {
+		let {breadcrumbs: {selectedKeys = []} = {}} = data;
+		let dispatch = action => store.dispatch(action);
+		let {softwareProductList, softwareProduct: {softwareProductEditor: {data: {id: currentSoftwareProductId, version: currentSoftwareProductVersion} = {}}},
+			licenseModelList, licenseModel: {licenseModelEditor: {data: {id: currentLicenseModelId, version: currentLicenseModelVersion} = {}}}} = store.getState();
+
+		if (this.programmaticBreadcrumbsUpdate) {
+			this.prevSelectedKeys = selectedKeys;
+			this.programmaticBreadcrumbsUpdate = false;
+			return;
+		}
+
+		if (!isEqual(selectedKeys, this.prevSelectedKeys)) {
+			this.breadcrumbsPrefixSelected = isEqual(selectedKeys, this.prevSelectedKeys && this.prevSelectedKeys.slice(0, selectedKeys.length));
+			this.prevSelectedKeys = selectedKeys;
+
+			if (selectedKeys.length === 0) {
+				OnboardingActionHelper.navigateToOnboardingCatalog(dispatch);
+			} else if (selectedKeys.length === 1 || selectedKeys[1] === enums.BREADCRUMS.LICENSE_MODEL) {
+				let [licenseModelId, , licenseModelScreen] = selectedKeys;
+				if (!licenseModelScreen) {
+					licenseModelScreen = enums.BREADCRUMS.LICENSE_AGREEMENTS;
+				}
+				if(currentLicenseModelId !== licenseModelId) {
+					currentLicenseModelVersion = licenseModelList.find(lm => lm.id === licenseModelId).version;
+				}
+				switch (licenseModelScreen) {
+					case enums.BREADCRUMS.LICENSE_AGREEMENTS:
+						OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version: currentLicenseModelVersion});
+						break;
+					case enums.BREADCRUMS.FEATURE_GROUPS:
+						OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version: currentLicenseModelVersion});
+						break;
+					case enums.BREADCRUMS.ENTITLEMENT_POOLS:
+						OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version: currentLicenseModelVersion});
+						break;
+					case enums.BREADCRUMS.LICENSE_KEY_GROUPS:
+						OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version: currentLicenseModelVersion});
+						break;
+				}
+			} else if (selectedKeys.length <= 4 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT) {
+				let [licenseModelId, , softwareProductId, softwareProductScreen] = selectedKeys;
+				let softwareProduct = softwareProductId ?
+					softwareProductList.find(({id}) => id === softwareProductId) :
+					softwareProductList.find(({vendorId}) => vendorId === licenseModelId);
+				if (!softwareProductId) {
+					softwareProductId = softwareProduct.id;
+				}
+				if(currentSoftwareProductId !== softwareProductId) {
+					currentSoftwareProductVersion = softwareProduct.version;
+				}
+				switch (softwareProductScreen) {
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_DETAILS:
+						OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId});
+						break;
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS:
+						OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId});
+						break;
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_PROCESSES:
+						OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+						break;
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS:
+						OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+						break;
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS:
+						OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+						dispatch({
+							type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM,
+							mapOfExpandedIds: {
+								[SoftwareProductNavigationItems.COMPONENTS]: true
+							}
+						});
+						break;
+					default:
+						OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+						break;
+				}
+			}else if (selectedKeys.length === 5 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT && selectedKeys[3] === enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS) {
+				let [licenseModelId, , softwareProductId, , componentId] = selectedKeys;
+				let softwareProduct = softwareProductId ?
+					softwareProductList.find(({id}) => id === softwareProductId) :
+					softwareProductList.find(({vendorId}) => vendorId === licenseModelId);
+				if (!softwareProductId) {
+					softwareProductId = softwareProduct.id;
+				}
+				if(currentSoftwareProductId !== softwareProductId) {
+					currentSoftwareProductVersion = softwareProduct.version;
+				}
+				OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
+			}else if (selectedKeys.length === 6 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT && selectedKeys[3] === enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS) {
+				let [licenseModelId, , softwareProductId, , componentId, componentScreen] = selectedKeys;
+				let softwareProduct = softwareProductId ?
+					softwareProductList.find(({id}) => id === softwareProductId) :
+					softwareProductList.find(({vendorId}) => vendorId === licenseModelId);
+				if (!softwareProductId) {
+					softwareProductId = softwareProduct.id;
+				}
+				if(currentSoftwareProductId !== softwareProductId) {
+					currentSoftwareProductVersion = softwareProduct.version;
+				}
+				switch (componentScreen) {
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
+						OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
+						break;
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
+						OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId});
+						break;
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
+						OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId});
+						break;
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
+						OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId});
+						break;
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
+						OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId});
+						break;
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
+						OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId});
+						break;
+					case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
+						OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId});
+						break;
+				}
+			} else {
+				console.error('Unknown breadcrumbs path: ', selectedKeys);
+			}
+		}
+	}
+
+	handleStoreChange() {
+		let {currentScreen, licenseModelList, softwareProductList} = store.getState();
+		let breadcrumbsData = {currentScreen, licenseModelList, softwareProductList};
+
+		if (!isEqual(breadcrumbsData, this.prevBreadcrumbsData) || this.breadcrumbsPrefixSelected) {
+			this.prevBreadcrumbsData = breadcrumbsData;
+			this.breadcrumbsPrefixSelected = false;
+			this.programmaticBreadcrumbsUpdate = true;
+
+			let breadcrumbs = this.buildBreadcrumbs(breadcrumbsData);
+			this.onEvent('breadcrumbsupdated', breadcrumbs);
+		}
+	}
+
+	buildBreadcrumbs({currentScreen: {screen, props}, licenseModelList, softwareProductList}) {
+		let componentsList;
+		if(props.componentId) {
+			componentsList = store.getState().softwareProduct.softwareProductComponents.componentsList;
+		}
+		let screenToBreadcrumb;
+		switch (screen) {
+			case enums.SCREEN.ONBOARDING_CATALOG:
+				return [];
+
+			case enums.SCREEN.LICENSE_AGREEMENTS:
+			case enums.SCREEN.FEATURE_GROUPS:
+			case enums.SCREEN.ENTITLEMENT_POOLS:
+			case enums.SCREEN.LICENSE_KEY_GROUPS:
+				screenToBreadcrumb = {
+					[enums.SCREEN.LICENSE_AGREEMENTS]: enums.BREADCRUMS.LICENSE_AGREEMENTS,
+					[enums.SCREEN.FEATURE_GROUPS]: enums.BREADCRUMS.FEATURE_GROUPS,
+					[enums.SCREEN.ENTITLEMENT_POOLS]: enums.BREADCRUMS.ENTITLEMENT_POOLS,
+					[enums.SCREEN.LICENSE_KEY_GROUPS]: enums.BREADCRUMS.LICENSE_KEY_GROUPS
+				};
+				return [
+					{
+						selectedKey: props.licenseModelId,
+						menuItems: licenseModelList.map(({id, vendorName}) => ({
+							key: id,
+							displayText: vendorName
+						}))
+					},
+					{
+						selectedKey: enums.BREADCRUMS.LICENSE_MODEL,
+						menuItems: [{
+							key: enums.BREADCRUMS.LICENSE_MODEL,
+							displayText: i18n('License Model')
+						},
+							...(softwareProductList.findIndex(({vendorId}) => vendorId === props.licenseModelId) === -1 ? [] : [{
+								key: enums.BREADCRUMS.SOFTWARE_PRODUCT,
+								displayText: i18n('Software Products')
+							}])]
+					}, {
+						selectedKey: screenToBreadcrumb[screen],
+						menuItems: [{
+							key: enums.BREADCRUMS.LICENSE_AGREEMENTS,
+							displayText: i18n('License Agreements')
+						}, {
+							key: enums.BREADCRUMS.FEATURE_GROUPS,
+							displayText: i18n('Feature Groups')
+						}, {
+							key: enums.BREADCRUMS.ENTITLEMENT_POOLS,
+							displayText: i18n('Entitlement Pools')
+						}, {
+							key: enums.BREADCRUMS.LICENSE_KEY_GROUPS,
+							displayText: i18n('License Key Groups')
+						}]
+					}
+				];
+
+			case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE:
+			case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS:
+			case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
+			case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
+			case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
+
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
+				screenToBreadcrumb = {
+					[enums.SCREEN.SOFTWARE_PRODUCT_DETAILS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_DETAILS,
+					[enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS,
+					[enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES]: enums.BREADCRUMS.SOFTWARE_PRODUCT_PROCESSES,
+					[enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS,
+					[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS
+				};
+				let componentScreenToBreadcrumb = {
+					[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_PROCESSES,
+					[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_COMPUTE,
+					[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_STORAGE,
+					[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_NETWORK,
+					[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_GENERAL,
+					[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING,
+					[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING
+				};
+				let licenseModelId = softwareProductList.find(({id}) => id === props.softwareProductId).vendorId;
+				let returnedBreadcrumb = [
+					{
+						selectedKey: licenseModelId,
+						menuItems: licenseModelList.map(({id, vendorName}) => ({
+							key: id,
+							displayText: vendorName
+						}))
+					},
+					{
+						selectedKey: enums.BREADCRUMS.SOFTWARE_PRODUCT,
+						menuItems: [{
+							key: enums.BREADCRUMS.LICENSE_MODEL,
+							displayText: i18n('License Model')
+						}, {
+							key: enums.BREADCRUMS.SOFTWARE_PRODUCT,
+							displayText: i18n('Software Products')
+						}]
+					},
+					{
+						selectedKey: props.softwareProductId,
+						menuItems: softwareProductList
+							.filter(({vendorId}) => vendorId === licenseModelId)
+							.map(({id, name}) => ({
+								key: id,
+								displayText: name
+							}))
+					},
+					...(screen === enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE ? [] : [{
+						selectedKey: screenToBreadcrumb[screen] || enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS,
+						menuItems: [{
+							key: enums.BREADCRUMS.SOFTWARE_PRODUCT_DETAILS,
+							displayText: i18n('General')
+						}, {
+							key: enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS,
+							displayText: i18n('Attachments')
+						}, {
+							key: enums.BREADCRUMS.SOFTWARE_PRODUCT_PROCESSES,
+							displayText: i18n('Process Details')
+						}, {
+							key: enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS,
+							displayText: i18n('Networks')
+						}, {
+							key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS,
+							displayText: i18n('Components')
+						}]
+					}])
+				];
+				if(props.componentId) {
+					returnedBreadcrumb = [
+						...returnedBreadcrumb, {
+							selectedKey: props.componentId,
+							menuItems: componentsList
+								.map(({id, displayName}) => ({
+									key: id,
+									displayText: displayName
+								}))
+						},
+						...[{
+							selectedKey: componentScreenToBreadcrumb[screen],
+							menuItems: [{
+								key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_GENERAL,
+								displayText: i18n('General')
+							}, {
+								key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_COMPUTE,
+								displayText: i18n('Compute')
+							}, {
+								key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING,
+								displayText: i18n('High Availability & Load Balancing')
+							}, {
+								key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_NETWORK,
+								displayText: i18n('Networks')
+							}, {
+								key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_STORAGE,
+								displayText: i18n('Storage')
+							}, {
+								key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_PROCESSES,
+								displayText: i18n('Process Details')
+							}, {
+								key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING,
+								displayText: i18n('Monitoring')
+							}]
+						}]
+					];
+				}
+				return returnedBreadcrumb;
+		}
+	}
+}
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js
new file mode 100644
index 0000000..9af2427
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes, enums} from './OnboardingConstants.js';
+
+export const currentScreenReducer = (state = {screen: enums.SCREEN.ONBOARDING_CATALOG, props: {}}, action) => {
+	if (action.type === actionTypes.SET_CURRENT_SCREEN) {
+		return action.currentScreen;
+	}
+	return state;
+};
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js
new file mode 100644
index 0000000..92d53a3
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {currentScreenReducer} from './OnboardingReducers.js';
+import licenseModelListReducer from './licenseModel/LicenseModelListReducer.js';
+import finalizedLicenseModelListReducer from './licenseModel/FinalizedLicenseModelListReducer.js';
+import licenseModelReducer from './licenseModel/LicenseModelReducer.js';
+import softwareProductReducer from './softwareProduct/SoftwareProductReducer.js';
+import softwareProductListReducer from './softwareProduct/SoftwareProductListReducer.js';
+
+
+export default {
+	currentScreen: currentScreenReducer,
+	licenseModelList: licenseModelListReducer,
+	finalizedLicenseModelList: finalizedLicenseModelListReducer,
+	licenseModel: licenseModelReducer,
+	softwareProduct: softwareProductReducer,
+	softwareProductList: softwareProductListReducer
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/FinalizedLicenseModelListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/FinalizedLicenseModelListReducer.js
new file mode 100644
index 0000000..a851e77
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/FinalizedLicenseModelListReducer.js
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './LicenseModelConstants.js';
+
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.FINALIZED_LICENSE_MODELS_LIST_LOADED:
+			return [...action.response.results];
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js
new file mode 100644
index 0000000..ad91a0d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js
@@ -0,0 +1,147 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import TabulatedEditor from 'src/nfvo-components/editor/TabulatedEditor.jsx';
+
+import {enums} from 'sdc-app/onboarding/OnboardingConstants.js';
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+
+import {navigationItems} from './LicenseModelConstants.js';
+import LicenseModelActionHelper from './LicenseModelActionHelper.js';
+import LicenseAgreementActionHelper from './licenseAgreement/LicenseAgreementActionHelper.js';
+import FeatureGroupsActionHelper from './featureGroups/FeatureGroupsActionHelper.js';
+import EntitlementPoolsActionHelper from './entitlementPools/EntitlementPoolsActionHelper.js';
+import LicenseKeyGroupsActionHelper from './licenseKeyGroups/LicenseKeyGroupsActionHelper.js';
+
+
+const buildNavigationBarProps = (licenseModel, screen) => {
+	const {id, vendorName, version} = licenseModel;
+	const meta = {version};
+
+	const groups = [{
+		id,
+		name: vendorName,
+		items: [
+			{
+				id: navigationItems.LICENSE_AGREEMENTS,
+				name: i18n('License Agreements'),
+				meta
+			},
+			{
+				id: navigationItems.FEATURE_GROUPS,
+				name: i18n('Feature Groups'),
+				meta
+			},
+			{
+				id: navigationItems.ENTITLEMENT_POOLS,
+				name: i18n('Entitlement Pools'),
+				meta
+			},
+			{
+				id: navigationItems.LICENSE_KEY_GROUPS,
+				name: i18n('License Key Groups'),
+				meta
+			}
+		]
+	}];
+
+	const activeItemId = ({
+		[enums.SCREEN.LICENSE_AGREEMENTS]: navigationItems.LICENSE_AGREEMENTS,
+		[enums.SCREEN.FEATURE_GROUPS]: navigationItems.FEATURE_GROUPS,
+		[enums.SCREEN.ENTITLEMENT_POOLS]: navigationItems.ENTITLEMENT_POOLS,
+		[enums.SCREEN.LICENSE_KEY_GROUPS]: navigationItems.LICENSE_KEY_GROUPS
+	})[screen];
+
+	return {
+		activeItemId, groups
+	};
+};
+
+
+const buildVersionControllerProps = (licenseModel) => {
+	let {version, viewableVersions, status: currentStatus, lockingUser} = licenseModel;
+	let {status, isCheckedOut} = (currentStatus === versionStatusEnum.CHECK_OUT_STATUS) ?
+		VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser) :
+		{status: currentStatus, isCheckedOut: false};
+
+	return {
+		version,
+		viewableVersions,
+		status,
+		isCheckedOut
+	};
+};
+
+
+const mapStateToProps = ({licenseModel: {licenseModelEditor}}, {currentScreen: {screen}}) => {
+	return {
+		versionControllerProps: buildVersionControllerProps(licenseModelEditor.data),
+		navigationBarProps: buildNavigationBarProps(licenseModelEditor.data, screen)
+	};
+};
+
+
+const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {licenseModelId}}}) => {
+	return {
+		onVersionControllerAction: action =>
+			LicenseModelActionHelper.performVCAction(dispatch, {licenseModelId, action}).then(() => {
+				switch(screen) {
+					case enums.SCREEN.LICENSE_AGREEMENTS:
+						LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId});
+						break;
+					case enums.SCREEN.FEATURE_GROUPS:
+						FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId});
+						break;
+					case enums.SCREEN.ENTITLEMENT_POOLS:
+						EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId});
+						break;
+					case enums.SCREEN.LICENSE_KEY_GROUPS:
+						LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId});
+						break;
+				}
+			}),
+		onVersionSwitching: version => LicenseAgreementActionHelper.switchVersion(dispatch, {licenseModelId, version}),
+		onClose: () => OnboardingActionHelper.navigateToOnboardingCatalog(dispatch),
+
+		onNavigate: ({id, meta: {version}}) => {
+			switch(id) {
+				case navigationItems.LICENSE_AGREEMENTS:
+					OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version});
+					break;
+				case navigationItems.FEATURE_GROUPS:
+					OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version});
+					break;
+				case navigationItems.ENTITLEMENT_POOLS:
+					OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version});
+					break;
+				case navigationItems.LICENSE_KEY_GROUPS:
+					OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version});
+					break;
+			}
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(TabulatedEditor);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js
new file mode 100644
index 0000000..a379a2c
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js
@@ -0,0 +1,101 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import {actionTypes} from './LicenseModelConstants.js';
+import {actionsEnum as vcActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
+
+function baseUrl() {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-license-models/`;
+}
+
+function fetchLicenseModels() {
+	return RestAPIUtil.fetch(baseUrl());
+}
+
+function fetchFinalizedLicenseModels() {
+	return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Final`);
+}
+
+function fetchLicenseModelById(licenseModelId, version) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl()}${licenseModelId}${versionQuery}`);
+}
+
+function putLicenseModelAction(id, action) {
+	return RestAPIUtil.save(`${baseUrl()}${id}/actions`, {action: action});
+}
+
+const LicenseModelActionHelper = {
+
+	fetchLicenseModels(dispatch) {
+		return fetchLicenseModels().then(response => {
+			dispatch({
+				type: actionTypes.LICENSE_MODELS_LIST_LOADED,
+				response
+			});
+		});
+	},
+
+	fetchFinalizedLicenseModels(dispatch) {
+		return fetchFinalizedLicenseModels().then(response => dispatch({
+			type: actionTypes.FINALIZED_LICENSE_MODELS_LIST_LOADED,
+			response
+		}));
+
+	},
+
+	fetchLicenseModelById(dispatch, {licenseModelId, version}) {
+		return fetchLicenseModelById(licenseModelId, version).then(response => {
+			if(version) {
+				response.version = version;
+			}
+			dispatch({
+				type: actionTypes.LICENSE_MODEL_LOADED,
+				response
+			});
+		});
+	},
+
+	addLicenseModel(dispatch, {licenseModel}){
+		dispatch({
+			type: actionTypes.ADD_LICENSE_MODEL,
+			licenseModel
+		});
+	},
+
+	performVCAction(dispatch, {licenseModelId, action}) {
+		return putLicenseModelAction(licenseModelId, action).then(() => {
+			if(action === vcActionsEnum.SUBMIT){
+				dispatch({
+					type: NotificationConstants.NOTIFY_SUCCESS,
+					data: {title: i18n('Submit Succeeded'), msg: i18n('This license model successfully submitted'), timeout: 2000}
+				});
+			}
+			return LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId});
+		});
+	}
+};
+
+export default LicenseModelActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js
new file mode 100644
index 0000000..13fa9f5
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	LICENSE_MODEL_LOADED: null,
+	LICENSE_MODELS_LIST_LOADED: null,
+	FINALIZED_LICENSE_MODELS_LIST_LOADED: null,
+	ADD_LICENSE_MODEL: null,
+	EDIT_LICENSE_MODEL: null
+});
+
+export const navigationItems = keyMirror({
+	LICENSE_AGREEMENTS: 'License Agreements',
+	FEATURE_GROUPS: 'Feature Groups',
+	ENTITLEMENT_POOLS: 'Entitlement Pools',
+	LICENSE_KEY_GROUPS: 'License Key Groups'
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelEditorReducer.js
new file mode 100644
index 0000000..e92e32a
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelEditorReducer.js
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './LicenseModelConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.LICENSE_MODEL_LOADED:
+			return {
+				...state,
+				data: action.response
+			};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js
new file mode 100644
index 0000000..8874c4c
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './LicenseModelConstants.js';
+
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.LICENSE_MODELS_LIST_LOADED:
+			return [...action.response.results];
+		case actionTypes.ADD_LICENSE_MODEL:
+			return [...state, action.licenseModel];
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js
new file mode 100644
index 0000000..5982b9f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {combineReducers} from 'redux';
+
+import licenseModelCreationReducer from './creation/LicenseModelCreationReducer.js';
+import licenseModelEditorReducer from './LicenseModelEditorReducer.js';
+
+import licenseAgreementListReducer from './licenseAgreement/LicenseAgreementListReducer.js';
+import licenseAgreementEditorReducer from './licenseAgreement/LicenseAgreementEditorReducer.js';
+import {actionTypes as licenseAgreementActionTypes} from './licenseAgreement/LicenseAgreementConstants.js';
+
+import featureGroupsEditorReducer from './featureGroups/FeatureGroupsEditorReducer.js';
+import featureGroupsListReducer from './featureGroups/FeatureGroupsListReducer.js';
+import {actionTypes as featureGroupsActionConstants} from './featureGroups/FeatureGroupsConstants';
+
+import entitlementPoolsListReducer from './entitlementPools/EntitlementPoolsListReducer.js';
+import entitlementPoolsEditorReducer from './entitlementPools/EntitlementPoolsEditorReducer.js';
+import {actionTypes as entitlementPoolsConstants} from './entitlementPools/EntitlementPoolsConstants';
+
+import licenseKeyGroupsEditorReducer from './licenseKeyGroups/LicenseKeyGroupsEditorReducer.js';
+import licenseKeyGroupsListReducer from './licenseKeyGroups/LicenseKeyGroupsListReducer.js';
+import {actionTypes as licenseKeyGroupsConstants} from './licenseKeyGroups/LicenseKeyGroupsConstants.js';
+
+export default combineReducers({
+	licenseModelCreation: licenseModelCreationReducer,
+	licenseModelEditor: licenseModelEditorReducer,
+
+	licenseAgreement: combineReducers({
+		licenseAgreementEditor: licenseAgreementEditorReducer,
+		licenseAgreementList: licenseAgreementListReducer,
+		licenseAgreementToDelete: (state = false, action) => action.type === licenseAgreementActionTypes.LICENSE_AGREEMENT_DELETE_CONFIRM ? action.licenseAgreementToDelete : state
+	}),
+	featureGroup: combineReducers({
+		featureGroupEditor: featureGroupsEditorReducer,
+		featureGroupsList: featureGroupsListReducer,
+		featureGroupToDelete: (state = false, action) => action.type === featureGroupsActionConstants.FEATURE_GROUPS_DELETE_CONFIRM ? action.featureGroupToDelete : state
+	}),
+	entitlementPool: combineReducers({
+		entitlementPoolEditor: entitlementPoolsEditorReducer,
+		entitlementPoolsList: entitlementPoolsListReducer,
+		entitlementPoolToDelete: (state = false, action) => action.type === entitlementPoolsConstants.ENTITLEMENT_POOLS_DELETE_CONFIRM ? action.entitlementPoolToDelete : state
+	}),
+	licenseKeyGroup: combineReducers({
+		licenseKeyGroupsEditor: licenseKeyGroupsEditorReducer,
+		licenseKeyGroupsList: licenseKeyGroupsListReducer,
+		licenseKeyGroupToDelete: (state = false, action) => action.type === licenseKeyGroupsConstants.LICENSE_KEY_GROUPS_DELETE_CONFIRM ? action.licenseKeyGroupToDelete : state
+	}),
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js
new file mode 100644
index 0000000..63d0f27
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+import LicenseModelCreationActionHelper from './LicenseModelCreationActionHelper.js';
+import LicenseModelCreationView from './LicenseModelCreationView.jsx';
+
+const mapStateToProps = ({licenseModel: {licenseModelCreation}}) => licenseModelCreation;
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onDataChanged: deltaData => LicenseModelCreationActionHelper.dataChanged(dispatch, {deltaData}),
+		onCancel: () => LicenseModelCreationActionHelper.close(dispatch),
+		onSubmit: (licenseModel) => {
+			LicenseModelCreationActionHelper.close(dispatch);
+			LicenseModelCreationActionHelper.createLicenseModel(dispatch, {licenseModel}).then(licenseModelId => {
+				OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId});
+			});
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(LicenseModelCreationView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js
new file mode 100644
index 0000000..c2a0409
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+import {actionTypes} from './LicenseModelCreationConstants.js';
+
+function baseUrl() {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-license-models/`;
+}
+
+function createLicenseModel(licenseModel) {
+	return RestAPIUtil.create(baseUrl(), {
+		vendorName: licenseModel.vendorName,
+		description: licenseModel.description,
+		iconRef: 'icon'
+	});
+}
+
+
+export default {
+
+	open(dispatch) {
+		dispatch({
+			type: actionTypes.OPEN
+		});
+	},
+
+	close(dispatch){
+		dispatch({
+			type: actionTypes.CLOSE
+		});
+	},
+
+	dataChanged(dispatch, {deltaData}){
+		dispatch({
+			type: actionTypes.DATA_CHANGED,
+			deltaData
+		});
+	},
+
+	createLicenseModel(dispatch, {licenseModel}){
+		return createLicenseModel(licenseModel).then(response => {
+			LicenseModelActionHelper.addLicenseModel(dispatch, {
+				licenseModel: {
+					...licenseModel,
+					id: response.value
+				}
+			});
+			return response.value;
+		});
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js
new file mode 100644
index 0000000..603d177
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	OPEN: null,
+	CLOSE: null,
+	DATA_CHANGED: null
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js
new file mode 100644
index 0000000..a54d1b3
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './LicenseModelCreationConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.OPEN:
+			return {
+				...state,
+				data: {}
+			};
+		case actionTypes.CLOSE:
+			return {};
+		case actionTypes.DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx
new file mode 100644
index 0000000..4dccc9e
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx
@@ -0,0 +1,60 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+
+const LicenseModelPropType = React.PropTypes.shape({
+	id: React.PropTypes.string,
+	vendorName: React.PropTypes.string,
+	description: React.PropTypes.string
+});
+
+class LicenseModelCreationView extends React.Component {
+
+	static propTypes = {
+		data: LicenseModelPropType,
+		onDataChanged: React.PropTypes.func.isRequired,
+		onSubmit: React.PropTypes.func.isRequired,
+		onCancel: React.PropTypes.func.isRequired
+	};
+
+	render() {
+		let {data = {}, onDataChanged} = this.props;
+		let {vendorName, description} = data;
+		return (
+			<div>
+				<ValidationForm
+					ref='validationForm'
+					hasButtons={true}
+					onSubmit={ () => this.submit() }
+					onReset={ () => this.props.onCancel() }
+					labledButtons={true}>
+					<ValidationInput
+						value={vendorName}
+						label={i18n('Vendor Name')}
+						ref='vendor-name'
+						onChange={vendorName => onDataChanged({vendorName})}
+						validations={{maxLength: 25, required: true}}
+						type='text'
+						className='field-section'/>
+					<ValidationInput
+						value={description}
+						label={i18n('Description')}
+						ref='description'
+						onChange={description => onDataChanged({description})}
+						validations={{maxLength: 1000, required: true}}
+						type='textarea'
+						className='field-section'/>
+				</ValidationForm>
+			</div>
+		);
+	}
+
+
+	submit() {
+		const {data:licenseModel} = this.props;
+		this.props.onSubmit(licenseModel);
+	}
+}
+
+export default LicenseModelCreationView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
new file mode 100644
index 0000000..631597a
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
@@ -0,0 +1,149 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import {actionTypes as entitlementPoolsActionTypes } from './EntitlementPoolsConstants.js';
+import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+
+function baseUrl(licenseModelId) {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/entitlement-pools`;
+}
+
+function fetchEntitlementPoolsList(licenseModelId, version) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(licenseModelId)}${versionQuery}`);
+}
+
+function postEntitlementPool(licenseModelId, entitlementPool) {
+	return RestAPIUtil.create(baseUrl(licenseModelId), {
+		name: entitlementPool.name,
+		description: entitlementPool.description,
+		thresholdValue: entitlementPool.thresholdValue,
+		thresholdUnits: entitlementPool.thresholdUnits,
+		entitlementMetric: entitlementPool.entitlementMetric,
+		increments: entitlementPool.increments,
+		aggregationFunction: entitlementPool.aggregationFunction,
+		operationalScope: entitlementPool.operationalScope,
+		time: entitlementPool.time,
+		manufacturerReferenceNumber: entitlementPool.manufacturerReferenceNumber
+	});
+}
+
+
+function putEntitlementPool(licenseModelId, previousEntitlementPool, entitlementPool) {
+	return RestAPIUtil.save(`${baseUrl(licenseModelId)}/${entitlementPool.id}`, {
+		name: entitlementPool.name,
+		description: entitlementPool.description,
+		thresholdValue: entitlementPool.thresholdValue,
+		thresholdUnits: entitlementPool.thresholdUnits,
+		entitlementMetric: entitlementPool.entitlementMetric,
+		increments: entitlementPool.increments,
+		aggregationFunction: entitlementPool.aggregationFunction,
+		operationalScope: entitlementPool.operationalScope,
+		time: entitlementPool.time,
+		manufacturerReferenceNumber: entitlementPool.manufacturerReferenceNumber
+	});
+}
+
+function deleteEntitlementPool(licenseModelId, entitlementPoolId) {
+	return RestAPIUtil.destroy(`${baseUrl(licenseModelId)}/${entitlementPoolId}`);
+}
+
+
+export default {
+	fetchEntitlementPoolsList(dispatch, {licenseModelId, version}) {
+		return fetchEntitlementPoolsList(licenseModelId, version).then(response => dispatch({
+			type: entitlementPoolsActionTypes.ENTITLEMENT_POOLS_LIST_LOADED,
+			response
+		}));
+	},
+
+	openEntitlementPoolsEditor(dispatch, {entitlementPool} = {}) {
+		dispatch({
+			type: entitlementPoolsActionTypes.entitlementPoolsEditor.OPEN,
+			entitlementPool
+		});
+	},
+
+	deleteEntitlementPool(dispatch, {licenseModelId, entitlementPoolId}) {
+		return deleteEntitlementPool(licenseModelId, entitlementPoolId).then(() => {
+			dispatch({
+				type: entitlementPoolsActionTypes.DELETE_ENTITLEMENT_POOL,
+				entitlementPoolId
+			});
+		});
+	},
+
+	entitlementPoolsEditorDataChanged(dispatch, {deltaData}) {
+		dispatch({
+			type: entitlementPoolsActionTypes.entitlementPoolsEditor.DATA_CHANGED,
+			deltaData
+		});
+	},
+
+	closeEntitlementPoolsEditor(dispatch) {
+		dispatch({
+			type: entitlementPoolsActionTypes.entitlementPoolsEditor.CLOSE
+		});
+	},
+
+	saveEntitlementPool(dispatch, {licenseModelId, previousEntitlementPool, entitlementPool}) {
+		if (previousEntitlementPool) {
+			return putEntitlementPool(licenseModelId, previousEntitlementPool, entitlementPool).then(() => {
+				dispatch({
+					type: entitlementPoolsActionTypes.EDIT_ENTITLEMENT_POOL,
+					entitlementPool
+				});
+			});
+		}
+		else {
+			return postEntitlementPool(licenseModelId, entitlementPool).then(response => {
+				dispatch({
+					type: entitlementPoolsActionTypes.ADD_ENTITLEMENT_POOL,
+					entitlementPool: {
+						...entitlementPool,
+						id: response.value
+					}
+				});
+			});
+		}
+	},
+
+	hideDeleteConfirm(dispatch) {
+		dispatch({
+			type: entitlementPoolsActionTypes.ENTITLEMENT_POOLS_DELETE_CONFIRM,
+			entitlementPoolToDelete: false
+		});
+	},
+	openDeleteEntitlementPoolConfirm(dispatch, {entitlementPool}) {
+		dispatch({
+			type: entitlementPoolsActionTypes.ENTITLEMENT_POOLS_DELETE_CONFIRM,
+			entitlementPoolToDelete: entitlementPool
+		});
+	},
+
+	switchVersion(dispatch, {licenseModelId, version}) {
+		LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
+			this.fetchEntitlementPoolsList(dispatch, {licenseModelId, version});
+		});
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx
new file mode 100644
index 0000000..04f038f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx
@@ -0,0 +1,51 @@
+import React from 'react';
+import {connect} from 'react-redux';
+import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
+import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+function renderMsg(entitlementPoolToDelete) {
+	let poolName = entitlementPoolToDelete ? entitlementPoolToDelete.name : '';
+	let msg = i18n('Are you sure you want to delete "{poolName}"?', {poolName});
+	let subMsg = entitlementPoolToDelete
+	&& entitlementPoolToDelete.referencingFeatureGroups
+	&& entitlementPoolToDelete.referencingFeatureGroups.length > 0 ?
+		i18n('This entitlement pool is associated with one or more feature groups') :
+		'';
+	return (
+		<div>
+			<p>{msg}</p>
+			<p>{subMsg}</p>
+		</div>
+	);
+};
+
+const mapStateToProps = ({licenseModel: {entitlementPool}}, {licenseModelId}) => {
+	let {entitlementPoolToDelete} = entitlementPool;
+	const show = entitlementPoolToDelete !== false;
+	return {
+		show,
+		title: 'Warning!',
+		type: 'warning',
+		msg: renderMsg(entitlementPoolToDelete),
+		confirmationDetails: {entitlementPoolToDelete, licenseModelId}
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onConfirmed: ({entitlementPoolToDelete, licenseModelId}) => {
+			EntitlementPoolsActionHelper.deleteEntitlementPool(dispatch, {
+				licenseModelId,
+				entitlementPoolId: entitlementPoolToDelete.id
+			});
+			EntitlementPoolsActionHelper.hideDeleteConfirm(dispatch);
+		},
+		onDeclined: () => {
+			EntitlementPoolsActionHelper.hideDeleteConfirm(dispatch);
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
new file mode 100644
index 0000000..8a85507
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
@@ -0,0 +1,112 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+export const actionTypes = keyMirror({
+
+	ENTITLEMENT_POOLS_LIST_LOADED: null,
+	ADD_ENTITLEMENT_POOL: null,
+	EDIT_ENTITLEMENT_POOL: null,
+	DELETE_ENTITLEMENT_POOL: null,
+	ENTITLEMENT_POOLS_DELETE_CONFIRM: null,
+
+	entitlementPoolsEditor: {
+		OPEN: null,
+		CLOSE: null,
+		DATA_CHANGED: null,
+	}
+
+});
+
+export const enums = keyMirror({
+	SELECTED_FEATURE_GROUP_TAB: {
+		GENERAL: 1,
+		ENTITLEMENT_POOLS: 2,
+		LICENCE_KEY_GROUPS: 3
+	},
+	SELECTED_ENTITLEMENT_POOLS_BUTTONTAB: {
+		ASSOCIATED_ENTITLEMENT_POOLS: 1,
+		AVAILABLE_ENTITLEMENT_POOLS: 2
+	}
+});
+
+export const defaultState = {
+	ENTITLEMENT_POOLS_EDITOR_DATA: {
+		entitlementMetric: {choice: '', other: ''},
+		aggregationFunction: {choice: '', other: ''},
+		operationalScope: {choices: [], other: ''},
+		time: {choice: '', other: ''}
+	}
+};
+
+export const thresholdUnitType = {
+	ABSOLUTE: 'Absolute',
+	PERCENTAGE: 'Percentage'
+};
+
+export const optionsInputValues = {
+	OPERATIONAL_SCOPE: [
+		{enum: '', title: i18n('please select…')},
+		{enum: 'Network_Wide', title: 'Network Wide'},
+		{enum: 'Availability_Zone', title: 'Availability Zone'},
+		{enum: 'Data_Center', title: 'Data Center'},
+		{enum: 'Tenant', title: 'Tenant'},
+		{enum: 'VM', title: 'VM'},
+		{enum: 'CPU', title: 'CPU'},
+		{enum: 'Core', title: 'Core'}
+	],
+	TIME: [
+		{enum: '', title: i18n('please select…')},
+		{enum: 'Hour', title: 'Hour'},
+		{enum: 'Day', title: 'Day'},
+		{enum: 'Month', title: 'Month'}
+	],
+	AGGREGATE_FUNCTION: [
+		{enum: '', title: i18n('please select…')},
+		{enum: 'Peak', title: 'Peak'},
+		{enum: 'Average', title: 'Average'}
+	],
+	ENTITLEMENT_METRIC: [
+		{enum: '', title: i18n('please select…')},
+		{enum: 'Software_Instances_Count', title: 'Software Instances'},
+		{enum: 'Core', title: 'Core'},
+		{enum: 'CPU', title: 'CPU'},
+		{enum: 'Trunks', title: 'Trunks'},
+		{enum: 'User', title: 'User'},
+		{enum: 'Subscribers', title: 'Subscribers'},
+		{enum: 'Tenants', title: 'Tenants'},
+		{enum: 'Tokens', title: 'Tokens'},
+		{enum: 'Seats', title: 'Seats'},
+		{enum: 'Units_TB', title: 'Units-TB'},
+		{enum: 'Units_GB', title: 'Units-GB'},
+		{enum: 'Units_MB', title: 'Units-MB'}
+	],
+	THRESHOLD_UNITS: [
+		{enum: '', title: i18n('please select…')},
+		{enum: thresholdUnitType.ABSOLUTE, title: 'Absolute'},
+		{enum: thresholdUnitType.PERCENTAGE, title: '%'}
+	]
+};
+
+
+
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js
new file mode 100644
index 0000000..d5bd07e
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js';
+import EntitlementPoolsEditorView from './EntitlementPoolsEditorView.jsx';
+
+const mapStateToProps = ({licenseModel: {entitlementPool}}) => {
+
+
+	let {data} = entitlementPool.entitlementPoolEditor;
+	
+	let previousData;
+	const entitlementPoolId = data ? data.id : null;
+	if(entitlementPoolId) {
+		previousData = entitlementPool.entitlementPoolsList.find(entitlementPool => entitlementPool.id === entitlementPoolId);
+	}
+
+	return {
+		data,
+		previousData
+	};
+};
+
+const mapActionsToProps = (dispatch, {licenseModelId}) => {
+	return {
+		onDataChanged: deltaData => EntitlementPoolsActionHelper.entitlementPoolsEditorDataChanged(dispatch, {deltaData}),
+		onCancel: () => EntitlementPoolsActionHelper.closeEntitlementPoolsEditor(dispatch),
+		onSubmit: ({previousEntitlementPool, entitlementPool}) => {
+			EntitlementPoolsActionHelper.closeEntitlementPoolsEditor(dispatch);
+			EntitlementPoolsActionHelper.saveEntitlementPool(dispatch, {licenseModelId, previousEntitlementPool, entitlementPool});
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(EntitlementPoolsEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
new file mode 100644
index 0000000..86e97ec
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes, defaultState} from './EntitlementPoolsConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.entitlementPoolsEditor.OPEN:
+			return {
+				...state,
+				data: action.entitlementPool ? {...action.entitlementPool} : defaultState.ENTITLEMENT_POOLS_EDITOR_DATA
+			};
+		case actionTypes.entitlementPoolsEditor.DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		case actionTypes.entitlementPoolsEditor.CLOSE:
+			return {};
+		default:
+			return state;
+	}
+
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
new file mode 100644
index 0000000..77c5a12
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
@@ -0,0 +1,167 @@
+import React from 'react';
+
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import {optionsInputValues as  EntitlementPoolsOptionsInputValues, thresholdUnitType}  from  './EntitlementPoolsConstants.js';
+import {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+
+
+const EntitlementPoolPropType = React.PropTypes.shape({
+	id: React.PropTypes.string,
+	name: React.PropTypes.string,
+	description: React.PropTypes.string,
+	manufacturerReferenceNumber: React.PropTypes.string,
+	operationalScope: React.PropTypes.shape({
+		choices: React.PropTypes.array,
+		other: React.PropTypes.string
+	}),
+	aggregationFunction: React.PropTypes.shape({
+		choice: React.PropTypes.string,
+		other: React.PropTypes.string
+	}),
+	increments: React.PropTypes.string,
+	time: React.PropTypes.shape({
+		choice: React.PropTypes.string,
+		other: React.PropTypes.string
+	}),
+	entitlementMetric: React.PropTypes.shape({
+		choice: React.PropTypes.string,
+		other: React.PropTypes.string
+	})
+});
+
+class EntitlementPoolsEditorView extends React.Component {
+
+	static propTypes = {
+		data: EntitlementPoolPropType,
+		previousData: EntitlementPoolPropType,
+		isReadOnlyMode: React.PropTypes.bool,
+		onDataChanged: React.PropTypes.func.isRequired,
+		onSubmit: React.PropTypes.func.isRequired,
+		onCancel: React.PropTypes.func.isRequired
+	};
+
+	static defaultProps = {
+		data: {}
+	};
+
+	render() {
+		let {data = {}, onDataChanged, isReadOnlyMode} = this.props;
+		let {
+			name, description, manufacturerReferenceNumber, operationalScope, aggregationFunction, thresholdUnits, thresholdValue,
+			increments, time, entitlementMetric} = data;
+		let thresholdValueValidation = thresholdUnits === thresholdUnitType.PERCENTAGE ? {numeric: true, required: true, maxValue: 100} : {numeric: true, required: true};
+		let timeValidation = time && time.choice === optionInputOther.OTHER ? {numeric: true, required: true} : {required: true};
+
+		return (
+			<ValidationForm
+				ref='validationForm'
+				hasButtons={true}
+				onSubmit={ () => this.submit() }
+				onReset={ () => this.props.onCancel() }
+				labledButtons={true}
+				isReadOnlyMode={isReadOnlyMode}
+				className='entitlement-pools-form'>
+				<div className='entitlement-pools-form-row'>
+					<ValidationInput
+						onChange={name => onDataChanged({name})}
+						label={i18n('Name')}
+						value={name}
+						validations={{maxLength: 120, required: true}}
+						type='text'/>
+
+					<ValidationInput
+						isMultiSelect={true}
+						onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}})}
+						onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER], other: operationalScope}})}
+						multiSelectedEnum={operationalScope && operationalScope.choices}
+						label={i18n('Operational Scope')}
+						otherValue={operationalScope && operationalScope.other}
+						validations={{required: true}}
+						values={EntitlementPoolsOptionsInputValues.OPERATIONAL_SCOPE}/>
+
+				</div>
+				<div className='entitlement-pools-form-row'>
+					<ValidationInput
+						onChange={description => onDataChanged({description})}
+						label={i18n('Description')}
+						value={description}
+						validations={{maxLength: 1000, required: true}}
+						type='textarea'/>
+					<div className='entitlement-pools-form-row-group'>
+						<div className='entitlement-pools-form-row'>
+							<ValidationInput
+								onEnumChange={thresholdUnits => onDataChanged({thresholdUnits})}
+								selectedEnum={thresholdUnits}
+								label={i18n('Threshold Value')}
+								type='select'
+								values={EntitlementPoolsOptionsInputValues.THRESHOLD_UNITS}
+								validations={{required: true}}/>
+							<ValidationInput
+								className='entitlement-pools-form-row-threshold-value'
+								onChange={thresholdValue => onDataChanged({thresholdValue})}
+								value={thresholdValue}
+								validations={thresholdValueValidation}
+								type='text'/>
+						</div>
+
+						<ValidationInput
+							onEnumChange={entitlementMetric => onDataChanged({entitlementMetric:{choice: entitlementMetric, other: ''}})}
+							onOtherChange={entitlementMetric => onDataChanged({entitlementMetric:{choice: optionInputOther.OTHER, other: entitlementMetric}})}
+							selectedEnum={entitlementMetric && entitlementMetric.choice}
+							otherValue={entitlementMetric && entitlementMetric.other}
+							label={i18n('Entitlement Metric')}
+							validations={{required: true}}
+							values={EntitlementPoolsOptionsInputValues.ENTITLEMENT_METRIC}/>
+						<ValidationInput
+							onEnumChange={aggregationFunction => onDataChanged({aggregationFunction:{choice: aggregationFunction, other: ''}})}
+							onOtherChange={aggregationFunction => onDataChanged({aggregationFunction:{choice: optionInputOther.OTHER, other: aggregationFunction}})}
+							selectedEnum={aggregationFunction && aggregationFunction.choice}
+							otherValue={aggregationFunction && aggregationFunction.other}
+							validations={{required: true}}
+							label={i18n('Aggregate Function')}
+							values={EntitlementPoolsOptionsInputValues.AGGREGATE_FUNCTION}/>
+
+					</div>
+				</div>
+				<div className='entitlement-pools-form-row'>
+
+					<ValidationInput
+						onChange={manufacturerReferenceNumber => onDataChanged({manufacturerReferenceNumber})}
+						label={i18n('Manufacturer Reference Number')}
+						value={manufacturerReferenceNumber}
+						validations={{maxLength: 100, required: true}}
+						type='text'/>
+
+					<ValidationInput
+						onEnumChange={time => onDataChanged({time:{choice: time, other: ''}})}
+						onOtherChange={time => onDataChanged({time:{choice: optionInputOther.OTHER, other: time}})}
+						selectedEnum={time && time.choice}
+						otherValue={time && time.other}
+						validations={timeValidation}
+						label={i18n('Time')}
+						values={EntitlementPoolsOptionsInputValues.TIME}/>
+				</div>
+				<div className='entitlement-pools-form-row'>
+					<ValidationInput
+						onChange={increments => onDataChanged({increments})}
+						label={i18n('Increments')}
+						value={increments}
+						validations={{maxLength: 120}}
+						type='text'/>
+
+				</div>
+			</ValidationForm>
+		);
+	}
+
+	submit() {
+		const {data: entitlementPool, previousData: previousEntitlementPool} = this.props;
+		this.props.onSubmit({entitlementPool, previousEntitlementPool});
+	}
+}
+
+export default EntitlementPoolsEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js
new file mode 100644
index 0000000..4b21a2f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js';
+import EntitlementPoolsListEditorView from './EntitlementPoolsListEditorView.jsx';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+const mapStateToProps = ({licenseModel: {entitlementPool, licenseModelEditor}}) => {
+	let {entitlementPoolsList} = entitlementPool;
+	let {data} = entitlementPool.entitlementPoolEditor;
+
+	let {vendorName} = licenseModelEditor.data;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data);
+
+	return {
+		vendorName,
+		entitlementPoolsList,
+		isReadOnlyMode,
+		isDisplayModal: Boolean(data),
+		isModalInEditMode: Boolean(data && data.id),
+	};
+};
+
+const mapActionsToProps = (dispatch, {licenseModelId}) => {
+	return {
+		onAddEntitlementPoolClick: () => EntitlementPoolsActionHelper.openEntitlementPoolsEditor(dispatch),
+		onEditEntitlementPoolClick: entitlementPool => EntitlementPoolsActionHelper.openEntitlementPoolsEditor(dispatch, {entitlementPool}),
+		onDeleteEntitlementPool: entitlementPool => EntitlementPoolsActionHelper.openDeleteEntitlementPoolConfirm(dispatch, {
+			licenseModelId,
+			entitlementPool
+		})
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(EntitlementPoolsListEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
new file mode 100644
index 0000000..52df102
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
@@ -0,0 +1,132 @@
+import React from 'react';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+
+import EntitlementPoolsEditor from './EntitlementPoolsEditor.js';
+import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+import {optionsInputValues} from './EntitlementPoolsConstants';
+import EntitlementPoolsConfirmationModal from './EntitlementPoolsConfirmationModal.jsx';
+
+
+class EntitlementPoolsListEditorView extends React.Component {
+	static propTypes = {
+		vendorName: React.PropTypes.string,
+		licenseModelId: React.PropTypes.string.isRequired,
+		entitlementPoolsList: React.PropTypes.array,
+		isReadOnlyMode: React.PropTypes.bool.isRequired,
+		isDisplayModal: React.PropTypes.bool,
+		isModalInEditMode: React.PropTypes.bool,
+		onAddEntitlementPoolClick: React.PropTypes.func,
+		onEditEntitlementPoolClick: React.PropTypes.func,
+		onDeleteEntitlementPool: React.PropTypes.func,
+	};
+
+	static defaultProps = {
+		entitlementPoolsList: []
+	};
+
+	state = {
+		localFilter: ''
+	};
+
+	render() {
+		let {licenseModelId, vendorName, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
+		let {onAddEntitlementPoolClick} = this.props;
+		const {localFilter} = this.state;
+
+		return (
+			<div className='entitlement-pools-list-editor'>
+				<ListEditorView
+					title={i18n('Entitlement Pools for {vendorName} License Model', {vendorName})}
+					plusButtonTitle={i18n('Add Entitlement Pool')}
+					onAdd={onAddEntitlementPoolClick}
+					filterValue={localFilter}
+					onFilter={filter => this.setState({localFilter: filter})}
+					isReadOnlyMode={isReadOnlyMode}>
+					{this.filterList().map(entitlementPool => this.renderEntitlementPoolListItem(entitlementPool, isReadOnlyMode))}
+				</ListEditorView>
+				<Modal show={isDisplayModal} bsSize='large' animation={true} className='entitlement-pools-modal'>
+					<Modal.Header>
+						<Modal.Title>{`${isModalInEditMode ? i18n('Edit Entitlement Pool') : i18n('Create New Entitlement Pool')}`}</Modal.Title>
+					</Modal.Header>
+					<Modal.Body>
+						{
+							isDisplayModal && (
+								<EntitlementPoolsEditor  licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>
+							)
+						}
+					</Modal.Body>
+				</Modal>
+
+				<EntitlementPoolsConfirmationModal licenseModelId={licenseModelId}/>
+			</div>
+		);
+	}
+
+	filterList() {
+		let {entitlementPoolsList} = this.props;
+		let {localFilter} = this.state;
+		if(localFilter.trim()) {
+			const filter = new RegExp(escape(localFilter), 'i');
+			return entitlementPoolsList.filter(({name = '', description = ''}) => {
+				return escape(name).match(filter) || escape(description).match(filter);
+			});
+		}
+		else {
+			return entitlementPoolsList;
+		}
+	}
+
+	renderEntitlementPoolListItem(entitlementPool, isReadOnlyMode) {
+		let {id, name, description, thresholdValue, thresholdUnits, entitlementMetric, aggregationFunction,
+			manufacturerReferenceNumber, time} = entitlementPool;
+		let {onEditEntitlementPoolClick, onDeleteEntitlementPool} = this.props;
+		return (
+			<ListEditorItemView
+				key={id}
+				onSelect={() => onEditEntitlementPoolClick(entitlementPool)}
+				onDelete={() => onDeleteEntitlementPool(entitlementPool)}
+				className='list-editor-item-view'
+				isReadOnlyMode={isReadOnlyMode}>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Name')}</div>
+					<div className='text name'>{name}</div>
+				</div>
+
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Entitlement')}</div>
+					<div className='entitlement-parameters'>{`${this.extractValue(aggregationFunction)} ${this.extractValue(entitlementMetric)} per  ${this.extractValue(time)}`}</div>
+					<div className='entitlement-pools-count'>{`${thresholdValue ? thresholdValue : ''} ${this.extractUnits(thresholdUnits)}`}</div>
+				</div>
+
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Manufacturer Reference Number')}</div>
+					<div className='text contract-number'>{manufacturerReferenceNumber}</div>
+				</div>
+
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Description')}</div>
+					<div className='text description'>{description}</div>
+				</div>
+			</ListEditorItemView>
+		);
+	}
+
+
+
+	extractUnits(units) {
+		if (units === undefined) {return '';} //TODO fix it later
+		return units === 'Absolute' ? '' : '%';
+	}
+
+	extractValue(item) {
+		if (item === undefined) {return '';} //TODO fix it later
+
+		return  item ? item.choice === optionInputOther.OTHER ? item.other : InputOptions.getTitleByName(optionsInputValues, item.choice) : '';
+	}
+}
+
+export default EntitlementPoolsListEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js
new file mode 100644
index 0000000..63e351f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './EntitlementPoolsConstants';
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.ENTITLEMENT_POOLS_LIST_LOADED:
+			return [...action.response.results];
+		case actionTypes.ADD_ENTITLEMENT_POOL:
+			return [...state, action.entitlementPool];
+		case actionTypes.EDIT_ENTITLEMENT_POOL:
+			const indexForEdit = state.findIndex(entitlementPool => entitlementPool.id === action.entitlementPool.id);
+			return [...state.slice(0, indexForEdit), action.entitlementPool, ...state.slice(indexForEdit + 1)];
+		case actionTypes.DELETE_ENTITLEMENT_POOL:
+			return state.filter(entitlementPool => entitlementPool.id !== action.entitlementPoolId);
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditor.js
new file mode 100644
index 0000000..c2b269b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditor.js
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+
+import FeatureGroupsActionHelper from './FeatureGroupsActionHelper.js';
+import FeatureGroupEditorView from './FeatureGroupEditorView.jsx';
+
+const mapStateToProps = ({licenseModel: {featureGroup, entitlementPool, licenseKeyGroup}}) => {
+
+	const {featureGroupEditor} = featureGroup;
+
+	let {data, selectedTab, selectedEntitlementPoolsButtonTab, selectedLicenseKeyGroupsButtonTab} = featureGroupEditor;
+
+	let previousData;
+	const featureGroupId = data ? data.id : null;
+	if (featureGroupId) {
+		previousData = featureGroup.featureGroupsList.find(featureGroup => featureGroup.id === featureGroupId);
+	}
+	let {entitlementPoolsList = []} = entitlementPool;
+	let {licenseKeyGroupsList = []} = licenseKeyGroup;
+
+	return {
+		data,
+		previousData,
+		selectedTab,
+		selectedEntitlementPoolsButtonTab,
+		selectedLicenseKeyGroupsButtonTab,
+		entitlementPoolsList,
+		licenseKeyGroupsList
+	};
+};
+
+
+const mapActionsToProps = (dispatch, {licenseModelId}) => {
+	return {
+		onTabSelect: tab => FeatureGroupsActionHelper.selectEntitlementPoolsEditorTab(dispatch, {tab}),
+		onEntitlementPoolsButtonTabSelect: buttonTab => FeatureGroupsActionHelper.selectFeatureGroupsEditorEntitlementPoolsButtonTab(dispatch, {buttonTab}),
+		onLicenseKeyGroupsButtonTabSelect: buttonTab => FeatureGroupsActionHelper.selectFeatureGroupsEditorLicenseKeyGroupsButtonTab(dispatch, {buttonTab}),
+		onDataChanged: deltaData => FeatureGroupsActionHelper.featureGroupsEditorDataChanged(dispatch, {deltaData}),
+		onSubmit: (previousFeatureGroup, featureGroup) => {
+			FeatureGroupsActionHelper.closeFeatureGroupsEditor(dispatch);
+			FeatureGroupsActionHelper.saveFeatureGroup(dispatch, {licenseModelId, previousFeatureGroup, featureGroup});
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(FeatureGroupEditorView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx
new file mode 100644
index 0000000..6fecd16
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx
@@ -0,0 +1,339 @@
+import React from 'react';
+import ValidationTabs from 'nfvo-components/input/validation/ValidationTabs.jsx';
+import ValidationTab from 'nfvo-components/input/validation/ValidationTab.jsx';
+import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js';
+import Button from 'react-bootstrap/lib/Button.js';
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import DualListboxView from 'nfvo-components/input/dualListbox/DualListboxView.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorViewItem from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import {state as FeatureGroupStateConstants} from './FeatureGroupsConstants.js';
+
+const FeatureGroupsPropType = React.PropTypes.shape({
+	id: React.PropTypes.string,
+	name: React.PropTypes.string,
+	description: React.PropTypes.string,
+	partNumber: React.PropTypes.string,
+	entitlementPoolsIds: React.PropTypes.array(React.PropTypes.string),
+	licenseKeyGroupsIds: React.PropTypes.array(React.PropTypes.string)
+});
+
+class FeatureGroupEditorView extends React.Component {
+
+
+	static propTypes = {
+		data: FeatureGroupsPropType,
+		previousData: FeatureGroupsPropType,
+		isReadOnlyMode: React.PropTypes.bool,
+
+		onSubmit: React.PropTypes.func,
+		onCancel: React.PropTypes.func,
+
+		selectedTab: React.PropTypes.number,
+		onTabSelect: React.PropTypes.func,
+
+		selectedEntitlementPoolsButtonTab: React.PropTypes.number,
+		selectedLicenseKeyGroupsButtonTab: React.PropTypes.number,
+		onEntitlementPoolsButtonTabSelect: React.PropTypes.func,
+		onLicenseKeyGroupsButtonTabSelect: React.PropTypes.func,
+
+		entitlementPoolsList: DualListboxView.propTypes.availableList,
+		licenseKeyGroupsList: DualListboxView.propTypes.availableList
+	};
+
+
+	static defaultProps = {
+		data: {},
+		selectedTab: FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.GENERAL,
+		selectedEntitlementPoolsButtonTab: FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.ASSOCIATED_ENTITLEMENT_POOLS,
+		selectedLicenseKeyGroupsButtonTab: FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.ASSOCIATED_LICENSE_KEY_GROUPS
+	};
+
+	state = {
+		localEntitlementPoolsListFilter: '',
+		localLicenseKeyGroupsListFilter: ''
+	};
+
+
+	render() {
+		let {selectedTab, onTabSelect, isReadOnlyMode} = this.props;
+		return (
+			<ValidationForm
+				ref='validationForm'
+				hasButtons={true}
+				onSubmit={ () => this.submit() }
+				onReset={ () => this.props.onCancel() }
+				labledButtons={true}
+				isReadOnlyMode={isReadOnlyMode}
+				name='feature-group-validation-form'
+				className='feature-group-form'>
+				<ValidationTabs activeKey={onTabSelect ? selectedTab : undefined} onSelect={onTabSelect}>
+					{this.renderGeneralTab()}
+					{this.renderEntitlementPoolsTab()}
+					{this.renderLicenseKeyGroupsTab()}
+				</ValidationTabs>
+
+			</ValidationForm>
+		);
+	}
+
+	submit() {
+		const {data: featureGroup, previousData: previousFeatureGroup} = this.props;
+		this.props.onSubmit(previousFeatureGroup, featureGroup);
+	}
+
+	renderGeneralTab() {
+		let {data = {}, onDataChanged} = this.props;
+		let {name, description, partNumber} = data;
+		return (
+			<ValidationTab eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.GENERAL} title={i18n('General')}>
+				<div>
+					<ValidationInput
+						groupClassName='field-section'
+						onChange={name => onDataChanged({name})}
+						ref='name'
+						label={i18n('Name')}
+						value={name}
+						name='feature-group-name'
+						validations={{maxLength: 120, required: true}}
+						type='text'/>
+					<ValidationInput
+						groupClassName='field-section'
+						className='description-field'
+						onChange={description => onDataChanged({description})}
+						ref='description'
+						label={i18n('Description')}
+						value={description}
+						name='feature-group-description'
+						validations={{maxLength: 1000, required: true}}
+						type='textarea'/>
+					<ValidationInput
+						groupClassName='field-section'
+						onChange={partNumber => onDataChanged({partNumber})}
+						label={i18n('Part Number')}
+						value={partNumber}
+						validations={{required: true}}
+						type='text'/>
+				</div>
+			</ValidationTab>
+		);
+	}
+
+	renderEntitlementPoolsTab() {
+		let {selectedEntitlementPoolsButtonTab, onEntitlementPoolsButtonTabSelect, entitlementPoolsList} = this.props;
+		if (entitlementPoolsList.length > 0) {
+			return (
+				<ValidationTab
+					eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.ENTITLEMENT_POOLS}
+					title={i18n('Entitlement Pools')}>
+					<ButtonGroup>
+						{
+							this.renderButtonsTab(
+								FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.ASSOCIATED_ENTITLEMENT_POOLS,
+								selectedEntitlementPoolsButtonTab,
+								i18n('Associated Entitlement Pools'),
+								onEntitlementPoolsButtonTabSelect
+							)
+						}
+						{
+							this.renderButtonsTab(
+								FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.AVAILABLE_ENTITLEMENT_POOLS,
+								selectedEntitlementPoolsButtonTab,
+								i18n('Available Entitlement Pools'),
+								onEntitlementPoolsButtonTabSelect
+							)
+						}
+					</ButtonGroup>
+					{this.renderEntitlementPoolsButtonTabContent(selectedEntitlementPoolsButtonTab)}
+				</ValidationTab>
+			);
+		} else {
+			return (
+				<ValidationTab
+					eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.ENTITLEMENT_POOLS}
+					title={i18n('Entitlement Pools')}>
+					<p>{i18n('There is no available entitlement pools.')}</p>
+				</ValidationTab>
+			);
+		}
+	}
+
+	renderLicenseKeyGroupsTab() {
+		let {selectedLicenseKeyGroupsButtonTab, onLicenseKeyGroupsButtonTabSelect, licenseKeyGroupsList} = this.props;
+		if (licenseKeyGroupsList.length > 0) {
+			return (
+				<ValidationTab
+					eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS}
+					title={i18n('License Key Groups')}>
+					<ButtonGroup>
+						{
+							this.renderButtonsTab(
+								FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.ASSOCIATED_LICENSE_KEY_GROUPS,
+								selectedLicenseKeyGroupsButtonTab,
+								i18n('Associated License Key Groups'),
+								onLicenseKeyGroupsButtonTabSelect
+							)
+						}
+						{
+							this.renderButtonsTab(
+								FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.AVAILABLE_LICENSE_KEY_GROUPS,
+								selectedLicenseKeyGroupsButtonTab,
+								i18n('Available License Key Groups'),
+								onLicenseKeyGroupsButtonTabSelect
+							)
+						}
+					</ButtonGroup>
+					{this.renderLicenseKeyGroupsTabContent(selectedLicenseKeyGroupsButtonTab)}
+				</ValidationTab>
+			);
+		} else {
+			return (
+				<ValidationTab
+					eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS}
+					title={i18n('License Key Groups')}>
+					<p>{i18n('There is no available license key groups')}</p>
+				</ValidationTab>);
+		}
+	}
+
+	renderButtonsTab(buttonTab, selectedButtonTab, title, onClick) {
+		const isSelected = buttonTab === selectedButtonTab;
+		return (
+			<Button
+				className='button-tab'
+				active={isSelected}
+				onClick={() => !isSelected && onClick(buttonTab)}>
+				{ title }
+			</Button>
+		);
+	}
+
+	renderEntitlementPoolsButtonTabContent(selectedFeatureGroupsButtonTab) {
+		const {entitlementPoolsList = [], data: {entitlementPoolsIds = []}} = this.props;
+		let dualBoxTitle = {
+			left: i18n('Available Entitlement Pools'),
+			right: i18n('Selected Entitlement Pools')
+		};
+
+		if (entitlementPoolsList.length) {
+			const {localEntitlementPoolsListFilter} = this.state;
+			let selectedEntitlementPools = entitlementPoolsIds.map(entitlementPoolId => entitlementPoolsList.find(entitlementPool => entitlementPool.id === entitlementPoolId));
+
+			switch (selectedFeatureGroupsButtonTab) {
+				case FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.ASSOCIATED_ENTITLEMENT_POOLS:
+					if (selectedEntitlementPools.length) {
+						return (
+							<ListEditorView
+								className='thinner-list'
+								filterValue={localEntitlementPoolsListFilter}
+								onFilter={localEntitlementPoolsListFilter => this.setState({localEntitlementPoolsListFilter})}>
+								{this.filterAssociatedItems(selectedEntitlementPools, localEntitlementPoolsListFilter)
+									.map(entitlementPool => this.renderAssociatedListItem(entitlementPool
+										, FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.ENTITLEMENT_POOLS))}
+							</ListEditorView>
+						);
+					}
+					else {
+						return (
+							<div>
+								<br/>{i18n('There are currently no entitlement pools associated with this feature group. Click "Available Entitlement Pools" to associate.')}
+							</div>
+						);
+					}
+				case FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.AVAILABLE_ENTITLEMENT_POOLS:
+					return (
+						<DualListboxView
+							filterTitle={dualBoxTitle}
+							selectedValuesList={entitlementPoolsIds}
+							availableList={entitlementPoolsList}
+							onChange={ selectedValuesList => this.props.onDataChanged( { entitlementPoolsIds: selectedValuesList } )}/>
+					);
+			}
+		}
+	}
+
+	renderLicenseKeyGroupsTabContent(selectedFeatureGroupsButtonTab) {
+		const {licenseKeyGroupsList = [], data: {licenseKeyGroupsIds = []}} = this.props;
+		let dualBoxFilterTitle = {
+			left: i18n('Available License Key Groups'),
+			right: i18n('Selected License Key Groups')
+		};
+
+		if (licenseKeyGroupsList.length) {
+			const {localLicenseKeyGroupsListFilter} = this.state;
+			let selectedLicenseKeyGroups = licenseKeyGroupsIds.map(licenseKeyGroupId => licenseKeyGroupsList.find(licenseKeyGroup => licenseKeyGroup.id === licenseKeyGroupId));
+
+			switch (selectedFeatureGroupsButtonTab) {
+				case FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.ASSOCIATED_LICENSE_KEY_GROUPS:
+					if (selectedLicenseKeyGroups.length) {
+						return (
+							<ListEditorView
+								className='thinner-list'
+								filterValue={localLicenseKeyGroupsListFilter}
+								onFilter={localLicenseKeyGroupsListFilter => this.setState({localLicenseKeyGroupsListFilter})}>
+								{this.filterAssociatedItems(selectedLicenseKeyGroups, localLicenseKeyGroupsListFilter)
+									.map(licenseKeyGroup => this.renderAssociatedListItem(licenseKeyGroup
+										, FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS))}
+							</ListEditorView>
+						);
+					} else {
+						return (
+							<div className='no-items-msg'>
+								{i18n('There are currently no license key groups associated with this feature group. Click "Available License Key Groups" to associate.')}
+							</div>
+						);
+					}
+				case FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.AVAILABLE_LICENSE_KEY_GROUPS:
+					return (
+						<DualListboxView
+							filterTitle={dualBoxFilterTitle}
+							selectedValuesList={this.props.data.licenseKeyGroupsIds}
+							availableList={this.props.licenseKeyGroupsList}
+							onChange={ selectedValuesList => this.props.onDataChanged( { licenseKeyGroupsIds: selectedValuesList } )}/>
+					);
+			}
+		}
+	}
+
+
+	renderAssociatedListItem(listItem, itemType) {
+		let {isReadOnlyMode} = this.props;
+		return (
+			<ListEditorViewItem
+				key={listItem.id}
+				onDelete={() => this.deleteAssociatedItem(listItem.id, itemType)}
+				isReadOnlyMode={isReadOnlyMode}>
+				<div className='name'>{listItem.name}</div>
+				<div className='description'>{listItem.description}</div>
+			</ListEditorViewItem>
+		);
+	}
+
+	filterAssociatedItems(list, localList) {
+		if (localList) {
+			const filter = new RegExp(escape(localList), 'i');
+			return list.filter(({name = '', description = ''}) => name.match(filter) || description.match(filter));
+		}
+		else {
+			return list;
+		}
+	}
+
+	deleteAssociatedItem(id, type) {
+		const {data: {licenseKeyGroupsIds = [], entitlementPoolsIds = []}} = this.props;
+		if (type === FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS) {
+			this.props.onDataChanged({licenseKeyGroupsIds: licenseKeyGroupsIds.filter(listId => listId !== id)});
+		} else {
+			this.props.onDataChanged({entitlementPoolsIds: entitlementPoolsIds.filter(listId => listId !== id)});
+		}
+
+	}
+}
+
+
+export default FeatureGroupEditorView;
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js
new file mode 100644
index 0000000..9ea5a31
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import FeatureGroupsActionHelper  from './FeatureGroupsActionHelper.js';
+import FeatureGroupListEditorView from './FeatureGroupListEditorView.jsx';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+const mapStateToProps = ({licenseModel: {featureGroup, licenseModelEditor}}) => {
+	const {featureGroupEditor: {data}, featureGroupsList} = featureGroup;
+	let {vendorName} = licenseModelEditor.data;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data);
+
+	return {
+		vendorName,
+		featureGroupsModal: {
+			show: Boolean(data),
+			editMode: Boolean(data && data.id)
+		},
+		featureGroupsList,
+		isReadOnlyMode
+	};
+};
+
+
+const mapActionsToProps = (dispatch, {licenseModelId}) => {
+	return {
+		onDeleteFeatureGroupClick: (featureGroup) => FeatureGroupsActionHelper.openDeleteFeatureGroupConfirm(dispatch, {licenseModelId, featureGroup}),
+		onCancelFeatureGroupsEditor: () => FeatureGroupsActionHelper.closeFeatureGroupsEditor(dispatch),
+
+		onAddFeatureGroupClick: () => FeatureGroupsActionHelper.openFeatureGroupsEditor(dispatch, {licenseModelId}),
+		onEditFeatureGroupClick: featureGroup => FeatureGroupsActionHelper.openFeatureGroupsEditor(dispatch, {
+			featureGroup,
+			licenseModelId
+		})
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(FeatureGroupListEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx
new file mode 100644
index 0000000..d998f92
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx
@@ -0,0 +1,136 @@
+import React from 'react';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+
+import FeatureGroupEditor from './FeatureGroupEditor.js';
+import FeatureGroupsConfirmationModal from './FeatureGroupsConfirmationModal.jsx';
+
+class FeatureGroupListEditorView extends React.Component {
+	static propTypes = {
+		vendorName: React.PropTypes.string,
+		licenseModelId: React.PropTypes.string.isRequired,
+		featureGroupsModal: React.PropTypes.shape({
+			show: React.PropTypes.bool,
+			editMode: React.PropTypes.bool
+		}),
+		isReadOnlyMode: React.PropTypes.bool.isRequired,
+		onAddFeatureGroupClick: React.PropTypes.func,
+		onEditFeatureGroupClick: React.PropTypes.func,
+		onDeleteFeatureGroupClick: React.PropTypes.func,
+		onCancelFeatureGroupsEditor: React.PropTypes.func,
+		featureGroupsList: React.PropTypes.array
+	};
+
+	static defaultProps = {
+		featureGroupsList: [],
+		featureGroupsModal: {
+			show: false,
+			editMode: false
+		}
+	};
+
+	state = {
+		localFilter: ''
+	};
+
+	render() {
+		let {vendorName, licenseModelId, featureGroupsModal, isReadOnlyMode, onAddFeatureGroupClick} = this.props;
+		const {localFilter} = this.state;
+
+		return (
+			<div className='feature-groups-list-editor'>
+				<ListEditorView
+					title={i18n('Feature Groups for {vendorName} License Model', {vendorName})}
+					plusButtonTitle={i18n('Add Feature Group')}
+					filterValue={localFilter}
+					onFilter={filter => this.setState({localFilter: filter})}
+					onAdd={() => onAddFeatureGroupClick()}
+					isReadOnlyMode={isReadOnlyMode}>
+					{this.filterList().map(listItem => this.renderFeatureGroupListItem(listItem, isReadOnlyMode))}
+				</ListEditorView>
+				<Modal show={featureGroupsModal.show} bsSize='large' animation={true} className='feature-group-modal'>
+					<Modal.Header>
+						<Modal.Title>{`${featureGroupsModal.editMode ? i18n('Edit Feature Group') : i18n('Create New Feature Group')}`}</Modal.Title>
+					</Modal.Header>
+					<Modal.Body>
+						<FeatureGroupEditor
+							onCancel={() => this.closeFeatureGroupsEditor()}
+							licenseModelId={licenseModelId}
+							isReadOnlyMode={isReadOnlyMode}/>
+					</Modal.Body>
+				</Modal>
+
+				<FeatureGroupsConfirmationModal licenseModelId={licenseModelId}/>
+
+			</div>
+		);
+	}
+
+
+	renderFeatureGroupListItem(listItem, isReadOnlyMode) {
+		let {name, description, entitlementPoolsIds = [], licenseKeyGroupsIds = []} = listItem;
+		return (
+			<ListEditorItemView
+				key={listItem.id}
+				onDelete={() => this.deleteFeatureGroupItem(listItem)}
+				onSelect={() => this.editFeatureGroupItem(listItem)}
+				className='list-editor-item-view'
+				isReadOnlyMode={isReadOnlyMode}>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Name')}</div>
+					<div className='text name'>{name}</div>
+				</div>
+
+				<div className='list-editor-item-view-field'>
+					<div className='feature-groups-count-field'>
+						<div className='title'>{i18n('Entitlement')}</div>
+						<div className='title'>{i18n('Pools')}</div>
+						<div className='feature-groups-count-ep'>{entitlementPoolsIds.length || 0}</div>
+					</div>
+					<div className='feature-groups-count-field'>
+						<div className='title'>{i18n('License key')}</div>
+						<div className='title'>{i18n('Groups')}</div>
+						<div className='feature-groups-count-lk'>{licenseKeyGroupsIds.length || 0}</div>
+					</div>
+				</div>
+
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Description')}</div>
+					<div className='text description'>{description}</div>
+				</div>
+
+			</ListEditorItemView>
+		);
+	}
+
+	filterList() {
+		let {featureGroupsList} = this.props;
+		let {localFilter} = this.state;
+		if (localFilter.trim()) {
+			const filter = new RegExp(escape(localFilter), 'i');
+			return featureGroupsList.filter(({name = '', description = ''}) => {
+				return escape(name).match(filter) || escape(description).match(filter);
+			});
+		}
+		else {
+			return featureGroupsList;
+		}
+	}
+
+	closeFeatureGroupsEditor() {
+		this.props.onCancelFeatureGroupsEditor();
+	}
+
+	editFeatureGroupItem(featureGroup) {
+		this.props.onEditFeatureGroupClick(featureGroup);
+	}
+
+	deleteFeatureGroupItem(featureGroup) {
+		this.props.onDeleteFeatureGroupClick(featureGroup);
+	}
+}
+
+export default FeatureGroupListEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js
new file mode 100644
index 0000000..3776c01
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js
@@ -0,0 +1,165 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import {actionTypes as featureGroupsActionConstants} from './FeatureGroupsConstants.js';
+import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+import EntitlementPoolsActionHelper from 'sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js';
+import LicenseKeyGroupsActionHelper from 'sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js';
+
+function baseUrl(licenseModelId) {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/feature-groups`;
+}
+
+function fetchFeatureGroupsList(licenseModelId, version) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(licenseModelId)}${versionQuery}`);
+}
+
+function deleteFeatureGroup(licenseModelId, featureGroupId) {
+	return RestAPIUtil.destroy(`${baseUrl(licenseModelId)}/${featureGroupId}`);
+}
+
+function addFeatureGroup(licenseModelId, featureGroup) {
+	return RestAPIUtil.create(baseUrl(licenseModelId), {
+		name: featureGroup.name,
+		description: featureGroup.description,
+		partNumber: featureGroup.partNumber,
+		addedLicenseKeyGroupsIds: featureGroup.licenseKeyGroupsIds,
+		addedEntitlementPoolsIds: featureGroup.entitlementPoolsIds
+	});
+}
+
+function updateFeatureGroup(licenseModelId, previousFeatureGroup, featureGroup) {
+
+	const {licenseKeyGroupsIds = []} = featureGroup;
+	const {licenseKeyGroupsIds: prevLicenseKeyGroupsIds = []} = previousFeatureGroup;
+	const {entitlementPoolsIds = []} = featureGroup;
+	const {entitlementPoolsIds: prevEntitlementPoolsIds = []} = previousFeatureGroup;
+	return RestAPIUtil.save(`${baseUrl(licenseModelId)}/${featureGroup.id}`, {
+		name: featureGroup.name,
+		description: featureGroup.description,
+		partNumber: featureGroup.partNumber,
+		addedLicenseKeyGroupsIds: licenseKeyGroupsIds.filter(licenseKeyGroupId => prevLicenseKeyGroupsIds.indexOf(licenseKeyGroupId) === -1),
+		removedLicenseKeyGroupsIds: prevLicenseKeyGroupsIds.filter(prevLicenseKeyGroupId => licenseKeyGroupsIds.indexOf(prevLicenseKeyGroupId) === -1),
+		addedEntitlementPoolsIds: entitlementPoolsIds.filter(entitlementPoolId => prevEntitlementPoolsIds.indexOf(entitlementPoolId) === -1),
+		removedEntitlementPoolsIds: prevEntitlementPoolsIds.filter(prevEntitlementPoolId => entitlementPoolsIds.indexOf(prevEntitlementPoolId) === -1)
+
+	});
+}
+
+export default {
+	fetchFeatureGroupsList(dispatch, {licenseModelId, version}) {
+		return fetchFeatureGroupsList(licenseModelId, version).then(response => dispatch({
+			type: featureGroupsActionConstants.FEATURE_GROUPS_LIST_LOADED,
+			response
+		}));
+	},
+
+	deleteFeatureGroup(dispatch, {licenseModelId, featureGroupId}) {
+		return deleteFeatureGroup(licenseModelId, featureGroupId).then(() => dispatch({
+			type: featureGroupsActionConstants.DELETE_FEATURE_GROUPS,
+			featureGroupId
+		}));
+	},
+
+	saveFeatureGroup(dispatch, {licenseModelId, previousFeatureGroup, featureGroup}) {
+		if (previousFeatureGroup) {
+			return updateFeatureGroup(licenseModelId, previousFeatureGroup, featureGroup).then(() => dispatch({
+				type: featureGroupsActionConstants.EDIT_FEATURE_GROUPS,
+				featureGroup
+			}));
+		}
+		else {
+			return addFeatureGroup(licenseModelId, featureGroup).then(response => dispatch({
+				type: featureGroupsActionConstants.ADD_FEATURE_GROUPS,
+				featureGroup: {
+					...featureGroup,
+					id: response.value
+				}
+			}));
+		}
+	},
+
+	selectEntitlementPoolsEditorTab(dispatch, {tab}) {
+		dispatch({
+			type: featureGroupsActionConstants.featureGroupsEditor.SELECT_TAB,
+			tab
+		});
+	},
+
+	selectFeatureGroupsEditorEntitlementPoolsButtonTab(dispatch, {buttonTab}) {
+		dispatch({
+			type: featureGroupsActionConstants.featureGroupsEditor.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB,
+			buttonTab
+		});
+	},
+
+	selectFeatureGroupsEditorLicenseKeyGroupsButtonTab(dispatch, {buttonTab}) {
+		dispatch({
+			type: featureGroupsActionConstants.featureGroupsEditor.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB,
+			buttonTab
+		});
+	},
+
+	openFeatureGroupsEditor(dispatch, {featureGroup, licenseModelId}) {
+		EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId});
+		LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId});
+		dispatch({
+			type: featureGroupsActionConstants.featureGroupsEditor.OPEN,
+			featureGroup
+		});
+	},
+
+	closeFeatureGroupsEditor(dispatch) {
+		dispatch({
+			type: featureGroupsActionConstants.featureGroupsEditor.CLOSE
+		});
+	},
+
+	featureGroupsEditorDataChanged(dispatch, {deltaData}) {
+		dispatch({
+			type: featureGroupsActionConstants.featureGroupsEditor.DATA_CHANGED,
+			deltaData
+		});
+	},
+
+	hideDeleteConfirm(dispatch) {
+		dispatch({
+			type: featureGroupsActionConstants.FEATURE_GROUPS_DELETE_CONFIRM,
+			featureGroupToDelete: false
+		});
+	},
+
+	openDeleteFeatureGroupConfirm(dispatch, {featureGroup}) {
+		dispatch({
+			type: featureGroupsActionConstants.FEATURE_GROUPS_DELETE_CONFIRM,
+			featureGroupToDelete: featureGroup
+		});
+	},
+
+	switchVersion(dispatch, {licenseModelId, version}) {
+		LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
+			this.fetchFeatureGroupsList(dispatch, {licenseModelId, version});
+		});
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConfirmationModal.jsx
new file mode 100644
index 0000000..142ec3c
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConfirmationModal.jsx
@@ -0,0 +1,48 @@
+import React from 'react';
+import {connect} from 'react-redux';
+import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
+import FeatureGroupsActionHelper from './FeatureGroupsActionHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+function renderMsg(featureGroupToDelete) {
+	let name = featureGroupToDelete ? featureGroupToDelete.name : '';
+	let msg = i18n('Are you sure you want to delete "{name}"?', {name});
+	let subMsg = featureGroupToDelete
+	&& featureGroupToDelete.referencingLicenseAgreements
+	&& featureGroupToDelete.referencingLicenseAgreements.length > 0 ?
+		i18n('This feature group is associated with one ore more license agreements') :
+		'';
+	return (
+		<div>
+			<p>{msg}</p>
+			<p>{subMsg}</p>
+		</div>
+	);
+};
+
+const mapStateToProps = ({licenseModel: {featureGroup}}, {licenseModelId}) => {
+	let {featureGroupToDelete} = featureGroup;
+	const show = featureGroupToDelete !== false;
+	return {
+		show,
+		title: 'Warning!',
+		type: 'warning',
+		msg: renderMsg(featureGroupToDelete),
+		confirmationDetails: {featureGroupToDelete, licenseModelId}
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onConfirmed: ({featureGroupToDelete, licenseModelId}) => {
+			FeatureGroupsActionHelper.deleteFeatureGroup(dispatch, {featureGroupId: featureGroupToDelete.id, licenseModelId});
+			FeatureGroupsActionHelper.hideDeleteConfirm(dispatch);
+		},
+		onDeclined: () => {
+			FeatureGroupsActionHelper.hideDeleteConfirm(dispatch);
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js
new file mode 100644
index 0000000..e02c545
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	FEATURE_GROUPS_LIST_LOADED: null,
+	ADD_FEATURE_GROUPS: null,
+	EDIT_FEATURE_GROUPS: null,
+	DELETE_FEATURE_GROUPS: null,
+	FEATURE_GROUPS_DELETE_CONFIRM: null,
+
+
+	ENTITLEMENT_POOLS_LIST_LOADED: null,
+
+	featureGroupsEditor: {
+		OPEN: null,
+		CLOSE: null,
+		DATA_CHANGED: null,
+		SELECT_TAB: null,
+		SELECTED_ENTITLEMENT_POOLS_BUTTONTAB: null,
+		SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB: null
+	}
+});
+
+export const state = keyMirror({
+	SELECTED_FEATURE_GROUP_TAB: {
+		GENERAL: 1,
+		ENTITLEMENT_POOLS: 2,
+		LICENCE_KEY_GROUPS: 3
+	},
+	SELECTED_ENTITLEMENT_POOLS_BUTTONTAB: {
+		ASSOCIATED_ENTITLEMENT_POOLS: 1,
+		AVAILABLE_ENTITLEMENT_POOLS: 2
+	},
+	SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB: {
+		ASSOCIATED_LICENSE_KEY_GROUPS: 1,
+		AVAILABLE_LICENSE_KEY_GROUPS: 2
+	},
+});
+
+
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsEditorReducer.js
new file mode 100644
index 0000000..576a535
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsEditorReducer.js
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './FeatureGroupsConstants.js';
+
+
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.featureGroupsEditor.OPEN:
+			return {
+				...state,
+				data: action.featureGroup || {}
+			};
+		case actionTypes.featureGroupsEditor.DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		case actionTypes.featureGroupsEditor.CLOSE:
+			return {};
+		case actionTypes.featureGroupsEditor.SELECT_TAB:
+			return {
+				...state,
+				selectedTab: action.tab
+			};
+
+		case actionTypes.featureGroupsEditor.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB:
+			return {
+				...state,
+				selectedEntitlementPoolsButtonTab: action.buttonTab
+			};
+		case actionTypes.featureGroupsEditor.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB:
+			return {
+				...state,
+				selectedLicenseKeyGroupsButtonTab: action.buttonTab
+			};
+		default:
+			return state;
+	}
+
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsListReducer.js
new file mode 100644
index 0000000..5cf3248
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsListReducer.js
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './FeatureGroupsConstants.js';
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.FEATURE_GROUPS_LIST_LOADED:
+			return [...action.response.results];
+		case actionTypes.ADD_FEATURE_GROUPS:
+			return [...state, action.featureGroup];
+		case actionTypes.EDIT_FEATURE_GROUPS:
+			const indexForEdit = state.findIndex(featureGroup => featureGroup.id === action.featureGroup.id);
+			return [...state.slice(0, indexForEdit), action.featureGroup, ...state.slice(indexForEdit + 1)];
+		case actionTypes.DELETE_FEATURE_GROUPS:
+			return state.filter(featureGroup => featureGroup.id !== action.featureGroupId);
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js
new file mode 100644
index 0000000..9616b60
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js
@@ -0,0 +1,160 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import {actionTypes as licenseAgreementActionTypes} from './LicenseAgreementConstants.js';
+import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js';
+import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+
+function baseUrl(licenseModelId) {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/license-agreements`;
+}
+
+function fetchLicenseAgreementList(licenseModelId, version) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(licenseModelId)}${versionQuery}`);
+}
+
+function postLicenseAgreement(licenseModelId, licenseAgreement) {
+	return RestAPIUtil.create(baseUrl(licenseModelId), {
+		name: licenseAgreement.name,
+		description: licenseAgreement.description,
+		licenseTerm: licenseAgreement.licenseTerm,
+		requirementsAndConstrains: licenseAgreement.requirementsAndConstrains,
+		addedFeatureGroupsIds: licenseAgreement.featureGroupsIds
+	});
+}
+
+function putLicenseAgreement(licenseModelId, previousLicenseAgreement, licenseAgreement) {
+	const {featureGroupsIds = []} = licenseAgreement;
+	const {featureGroupsIds: prevFeatureGroupsIds = []} = previousLicenseAgreement;
+	return RestAPIUtil.save(`${baseUrl(licenseModelId)}/${licenseAgreement.id}`, {
+		name: licenseAgreement.name,
+		description: licenseAgreement.description,
+		licenseTerm: licenseAgreement.licenseTerm,
+		requirementsAndConstrains: licenseAgreement.requirementsAndConstrains,
+		addedFeatureGroupsIds: featureGroupsIds.filter(featureGroupId => prevFeatureGroupsIds.indexOf(featureGroupId) === -1),
+		removedFeatureGroupsIds: prevFeatureGroupsIds.filter(prevFeatureGroupsId => featureGroupsIds.indexOf(prevFeatureGroupsId) === -1)
+	});
+}
+
+function deleteLicenseAgreement(licenseModelId, licenseAgreementId) {
+	return RestAPIUtil.destroy(`${baseUrl(licenseModelId)}/${licenseAgreementId}`);
+}
+
+export default {
+
+	fetchLicenseAgreementList(dispatch, {licenseModelId, version}) {
+		return fetchLicenseAgreementList(licenseModelId, version).then(response => dispatch({
+			type: licenseAgreementActionTypes.LICENSE_AGREEMENT_LIST_LOADED,
+			response
+		}));
+	},
+
+	openLicenseAgreementEditor(dispatch, {licenseModelId, licenseAgreement}) {
+		FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId});
+		dispatch({
+			type: licenseAgreementActionTypes.licenseAgreementEditor.OPEN,
+			licenseAgreement
+		});
+	},
+
+	licenseAgreementEditorDataChanged(dispatch, {deltaData}) {
+		dispatch({
+			type: licenseAgreementActionTypes.licenseAgreementEditor.DATA_CHANGED,
+			deltaData
+		});
+	},
+
+	closeLicenseAgreementEditor(dispatch) {
+		dispatch({
+			type: licenseAgreementActionTypes.licenseAgreementEditor.CLOSE
+		});
+	},
+
+
+	saveLicenseAgreement(dispatch, {licenseModelId, previousLicenseAgreement, licenseAgreement}) {
+		if (previousLicenseAgreement) {
+			return putLicenseAgreement(licenseModelId, previousLicenseAgreement, licenseAgreement).then(() => {
+				dispatch({
+					type: licenseAgreementActionTypes.EDIT_LICENSE_AGREEMENT,
+					licenseAgreement
+				});
+			});
+		}
+		else {
+			return postLicenseAgreement(licenseModelId, licenseAgreement).then(response => {
+				dispatch({
+					type: licenseAgreementActionTypes.ADD_LICENSE_AGREEMENT,
+					licenseAgreement: {
+						...licenseAgreement,
+						id: response.value
+					}
+				});
+			});
+		}
+	},
+
+	deleteLicenseAgreement(dispatch, {licenseModelId, licenseAgreementId}) {
+		return deleteLicenseAgreement(licenseModelId, licenseAgreementId).then(() => {
+			dispatch({
+				type: licenseAgreementActionTypes.DELETE_LICENSE_AGREEMENT,
+				licenseAgreementId
+			});
+		});
+	},
+
+	selectLicenseAgreementEditorTab(dispatch, {tab}) {
+		dispatch({
+			type: licenseAgreementActionTypes.licenseAgreementEditor.SELECT_TAB,
+			tab
+		});
+	},
+
+	selectLicenseAgreementEditorFeatureGroupsButtonTab(dispatch, {buttonTab}) {
+		dispatch({
+			type: licenseAgreementActionTypes.licenseAgreementEditor.SELECT_FEATURE_GROUPS_BUTTONTAB,
+			buttonTab
+		});
+	},
+
+	hideDeleteConfirm(dispatch) {
+		dispatch({
+			type: licenseAgreementActionTypes.LICENSE_AGREEMENT_DELETE_CONFIRM,
+			licenseAgreementToDelete: false
+		});
+	},
+
+	openDeleteLicenseAgreementConfirm(dispatch, {licenseAgreement} ) {
+		dispatch({
+			type: licenseAgreementActionTypes.LICENSE_AGREEMENT_DELETE_CONFIRM,
+			licenseAgreementToDelete: licenseAgreement
+		});
+	},
+
+	switchVersion(dispatch, {licenseModelId, version}) {
+		LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
+			this.fetchLicenseAgreementList(dispatch, {licenseModelId, version});
+		});
+	}
+};
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConfirmationModal.jsx
new file mode 100644
index 0000000..42f2407
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConfirmationModal.jsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import {connect} from 'react-redux';
+import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
+import LicenseAgreementActionHelper from './LicenseAgreementActionHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+function renderMsg(licenseAgreementToDelete) {
+	let name = licenseAgreementToDelete ? licenseAgreementToDelete.name : '';
+	let msg = i18n('Are you sure you want to delete "{name}"?', {name});
+	return(
+		<div>
+			<p>{msg}</p>
+		</div>
+	);
+};
+
+const mapStateToProps = ({licenseModel: {licenseAgreement}}, {licenseModelId}) => {
+	let {licenseAgreementToDelete} = licenseAgreement;
+	const show = licenseAgreementToDelete !== false;
+	return {
+		show,
+		title: 'Warning!',
+		type: 'warning',
+		msg: renderMsg(licenseAgreementToDelete),
+		confirmationDetails: {licenseAgreementToDelete, licenseModelId}
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onConfirmed: ({licenseAgreementToDelete, licenseModelId}) => {
+
+			LicenseAgreementActionHelper.deleteLicenseAgreement(dispatch, {licenseModelId, licenseAgreementId: licenseAgreementToDelete.id});
+			LicenseAgreementActionHelper.hideDeleteConfirm(dispatch);
+		},
+		onDeclined: () => {
+			LicenseAgreementActionHelper.hideDeleteConfirm(dispatch);
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js
new file mode 100644
index 0000000..af5c454
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+export const actionTypes = keyMirror({
+	LICENSE_AGREEMENT_LIST_LOADED: null,
+	ADD_LICENSE_AGREEMENT: null,
+	EDIT_LICENSE_AGREEMENT: null,
+	DELETE_LICENSE_AGREEMENT: null,
+	LICENSE_AGREEMENT_DELETE_CONFIRM: null,
+
+	licenseAgreementEditor: {
+		OPEN: null,
+		CLOSE: null,
+		DATA_CHANGED: null,
+		SELECT_TAB: null,
+		SELECT_FEATURE_GROUPS_BUTTONTAB: null,
+	}
+
+});
+
+export const enums = keyMirror({
+	SELECTED_LICENSE_AGREEMENT_TAB: {
+		GENERAL: 1,
+		FEATURE_GROUPS: 2
+	},
+
+	SELECTED_FEATURE_GROUPS_BUTTONTAB: {
+		ASSOCIATED_FEATURE_GROUPS: 1,
+		AVAILABLE_FEATURE_GROUPS: 2
+	}
+});
+
+export const defaultState = {
+	LICENSE_AGREEMENT_EDITOR_DATA: {
+		licenseTerm: {choice: '', other: ''}
+	}
+};
+
+export const optionsInputValues = {
+	LICENSE_MODEL_TYPE: [
+		{enum: '', title: i18n('please select…')},
+		{enum: 'Fixed_Term', title: 'Fixed Term'},
+		{enum: 'Perpetual', title: 'Perpetual'},
+		{enum: 'Unlimited', title: 'Unlimited'}
+	]
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditor.js
new file mode 100644
index 0000000..6a3e4db
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditor.js
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import LicenseAgreementActionHelper from './LicenseAgreementActionHelper.js';
+import LicenseAgreementEditorView from './LicenseAgreementEditorView.jsx';
+
+export const mapStateToProps = ({licenseModel: {licenseAgreement, featureGroup}}) => {
+
+
+	let {data, selectedTab, selectedFeatureGroupsButtonTab} = licenseAgreement.licenseAgreementEditor;
+
+	let previousData;
+	const licenseAgreementId = data ? data.id : null;
+	if(licenseAgreementId) {
+		previousData = licenseAgreement.licenseAgreementList.find(licenseAgreement => licenseAgreement.id === licenseAgreementId);
+	}
+
+	const {featureGroupsList = []} = featureGroup;
+
+	return {
+		data,
+		previousData,
+		selectedTab,
+		selectedFeatureGroupsButtonTab,
+		featureGroupsList
+	};
+};
+
+export const mapActionsToProps = (dispatch, {licenseModelId}) => {
+	return {
+		onDataChanged: deltaData => LicenseAgreementActionHelper.licenseAgreementEditorDataChanged(dispatch, {deltaData}),
+		onTabSelect: tab => LicenseAgreementActionHelper.selectLicenseAgreementEditorTab(dispatch, {tab}),
+		onFeatureGroupsButtonTabSelect: buttonTab => LicenseAgreementActionHelper.selectLicenseAgreementEditorFeatureGroupsButtonTab(dispatch, {buttonTab}),
+		onCancel: () => LicenseAgreementActionHelper.closeLicenseAgreementEditor(dispatch),
+		onSubmit: ({previousLicenseAgreement, licenseAgreement}) => {
+			LicenseAgreementActionHelper.closeLicenseAgreementEditor(dispatch);
+			LicenseAgreementActionHelper.saveLicenseAgreement(dispatch, {licenseModelId, previousLicenseAgreement, licenseAgreement});
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(LicenseAgreementEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorReducer.js
new file mode 100644
index 0000000..74e2f6e
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorReducer.js
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes, defaultState} from './LicenseAgreementConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.licenseAgreementEditor.OPEN:
+			return {
+				...state,
+				data: action.licenseAgreement ? { ...action.licenseAgreement } : defaultState.LICENSE_AGREEMENT_EDITOR_DATA
+			};
+		case actionTypes.licenseAgreementEditor.DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		case actionTypes.licenseAgreementEditor.CLOSE:
+			return {};
+		case actionTypes.licenseAgreementEditor.SELECT_TAB:
+			return {
+				...state,
+				selectedTab: action.tab
+			};
+		case actionTypes.licenseAgreementEditor.SELECT_FEATURE_GROUPS_BUTTONTAB:
+			return {
+				...state,
+				selectedFeatureGroupsButtonTab: action.buttonTab
+			};
+		default:
+			return state;
+	}
+
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx
new file mode 100644
index 0000000..b21f943
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx
@@ -0,0 +1,247 @@
+import React from 'react';
+import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js';
+import Button from 'react-bootstrap/lib/Button.js';
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationTabs from 'nfvo-components/input/validation/ValidationTabs.jsx';
+import ValidationTab from 'nfvo-components/input/validation/ValidationTab.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import DualListboxView from 'nfvo-components/input/dualListbox/DualListboxView.jsx';
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorViewItem from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import {enums as LicenseAgreementEnums, optionsInputValues as LicenseAgreementOptionsInputValues} from './LicenseAgreementConstants.js';
+
+
+const LicenseAgreementPropType = React.PropTypes.shape({
+	id: React.PropTypes.string,
+	name: React.PropTypes.string,
+	description: React.PropTypes.string,
+	requirementsAndConstrains: React.PropTypes.string,
+	licenseTerm: React.PropTypes.object,
+	featureGroupsIds: React.PropTypes.arrayOf(React.PropTypes.string)
+});
+
+class LicenseAgreementEditorView extends React.Component {
+
+	static propTypes = {
+		data: LicenseAgreementPropType,
+		previousData: LicenseAgreementPropType,
+		isReadOnlyMode: React.PropTypes.bool,
+		onDataChanged: React.PropTypes.func.isRequired,
+		onSubmit: React.PropTypes.func.isRequired,
+		onCancel: React.PropTypes.func.isRequired,
+
+		selectedTab: React.PropTypes.number,
+		onTabSelect: React.PropTypes.func,
+
+		selectedFeatureGroupsButtonTab: React.PropTypes.number,
+		onFeatureGroupsButtonTabSelect: React.PropTypes.func,
+		featureGroupsList: DualListboxView.propTypes.availableList
+	};
+
+	static defaultProps = {
+		selectedTab: LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL,
+		selectedFeatureGroupsButtonTab: LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.AVAILABLE_FEATURE_GROUPS,
+		data: {}
+	};
+
+	state = {
+		localFeatureGroupsListFilter: ''
+	};
+
+	render() {
+		let {selectedTab, onTabSelect, isReadOnlyMode} = this.props;
+		return (
+			<ValidationForm
+				ref='validationForm'
+				hasButtons={true}
+				onSubmit={ () => this.submit() }
+				onReset={ () => this.props.onCancel() }
+				labledButtons={true}
+				isReadOnlyMode={isReadOnlyMode}
+				className='license-agreement-form'>
+				<ValidationTabs activeKey={onTabSelect ? selectedTab : undefined} onSelect={onTabSelect}>
+					{this.renderGeneralTab()}
+					{this.renderFeatureGroupsTab()}
+				</ValidationTabs>
+			</ValidationForm>
+		);
+	}
+
+	submit() {
+		const {data: licenseAgreement, previousData: previousLicenseAgreement} = this.props;
+		this.props.onSubmit({licenseAgreement, previousLicenseAgreement});
+	}
+
+	renderGeneralTab() {
+		let {data = {}, onDataChanged} = this.props;
+		let {name, description, requirementsAndConstrains, licenseTerm} = data;
+		return (
+			<ValidationTab
+				eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL}
+				title={i18n('General')}>
+				<div className='license-agreement-form-row'>
+					<div className='license-agreement-form-col'>
+						<ValidationInput
+							onChange={name => onDataChanged({name})}
+							label={i18n('Name')}
+							value={name}
+							name='license-agreement-name'
+							validations={{maxLength: 25, required: true}}
+							type='text'/>
+						<ValidationInput
+							onChange={requirementsAndConstrains => onDataChanged({requirementsAndConstrains})}
+							label={i18n('Requirements and Constraints')}
+							value={requirementsAndConstrains}
+							name='license-agreement-requirements-and-constraints'
+							validations={{maxLength: 1000}}
+							type='textarea'/>
+					</div>
+					<ValidationInput
+						onChange={description => onDataChanged({description})}
+						label={i18n('Description')}
+						value={description}
+						name='license-agreement-description'
+						validations={{maxLength: 1000, required: true}}
+						type='textarea'/>
+				</div>
+				<div className='license-agreement-form-row'>
+					<ValidationInput
+						onEnumChange={licenseTerm => onDataChanged({licenseTerm:{choice: licenseTerm, other: ''}})}
+						selectedEnum={licenseTerm && licenseTerm.choice}
+						validations={{required: true}}
+						type='select'
+						label={i18n('License Term')}
+						values={LicenseAgreementOptionsInputValues.LICENSE_MODEL_TYPE}/>
+				</div>
+			</ValidationTab>
+		);
+	}
+
+	renderFeatureGroupsTab() {
+		let {onFeatureGroupsButtonTabSelect, selectedFeatureGroupsButtonTab, featureGroupsList} = this.props;
+		if (featureGroupsList.length > 0) {
+			return (
+				<ValidationTab
+					eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.FEATURE_GROUPS}
+					title={i18n('Feature Groups')}>
+					<ButtonGroup>
+						{
+							this.renderFeatureGroupsButtonTab(
+								LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.ASSOCIATED_FEATURE_GROUPS,
+								selectedFeatureGroupsButtonTab,
+								i18n('Associated Feature Groups'),
+								onFeatureGroupsButtonTabSelect
+							)
+						}
+						{
+							this.renderFeatureGroupsButtonTab(
+								LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.AVAILABLE_FEATURE_GROUPS,
+								selectedFeatureGroupsButtonTab,
+								i18n('Available Feature Groups'),
+								onFeatureGroupsButtonTabSelect
+							)
+						}
+					</ButtonGroup>
+					{this.renderFeatureGroupsButtonTabContent(selectedFeatureGroupsButtonTab)}
+				</ValidationTab>
+			);
+		} else {
+			return (
+				<ValidationTab
+					eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.FEATURE_GROUPS}
+					title={i18n('Feature Groups')}>
+					<p>{i18n('There is no available feature groups')}</p>
+				</ValidationTab>
+			);
+		}
+	}
+
+	renderFeatureGroupsButtonTabContent(selectedFeatureGroupsButtonTab) {
+		const {featureGroupsList = [], data: {featureGroupsIds = []}} = this.props;
+		const {localFeatureGroupsListFilter} = this.state;
+		let selectedFeatureGroups = featureGroupsIds.map(featureGroupId => featureGroupsList.find(featureGroup => featureGroup.id === featureGroupId));
+
+		const dualBoxFilterTitle = {
+			left: i18n('Available Feature Groups'),
+			right: i18n('Selected Feature Groups')
+		};
+
+		switch (selectedFeatureGroupsButtonTab) {
+			case LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.ASSOCIATED_FEATURE_GROUPS:
+				if (!selectedFeatureGroups.length) {
+					return (
+						<div className='no-items-msg'>
+							{i18n('There are currently no feature groups associated with this license agreement. Click "Available Feature Groups" to associate.')}
+						</div>
+					);
+				}
+				if (featureGroupsList.length) {
+					return (
+						<ListEditorView
+							className='thinner-list'
+							filterValue={localFeatureGroupsListFilter}
+							onFilter={localFeatureGroupsListFilter => this.setState({localFeatureGroupsListFilter})}>
+							{this.filterAssociatedFeatureGroupsList(selectedFeatureGroups).map(featureGroup => this.renderAssociatedFeatureGroupListItem(featureGroup))}
+						</ListEditorView>
+					);
+				}
+				return;
+			case LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.AVAILABLE_FEATURE_GROUPS:
+				return (
+					<DualListboxView
+						filterTitle={dualBoxFilterTitle}
+						selectedValuesList={this.props.data.featureGroupsIds}
+						availableList={this.props.featureGroupsList}
+						onChange={ selectedValuesList => this.props.onDataChanged( { featureGroupsIds: selectedValuesList } )}/>
+				);
+		}
+	}
+
+	renderFeatureGroupsButtonTab(buttonTab, selectedButtonTab, title, onClick) {
+		const isSelected = buttonTab === selectedButtonTab;
+		return (
+			<Button
+				className='button-tab'
+				active={isSelected}
+				onClick={() => !isSelected && onClick(buttonTab)}>
+				{ title }
+			</Button>
+		);
+	}
+
+	renderAssociatedFeatureGroupListItem({id, name, entitlementPoolsIds = [], licenseKeyGroupsIds = []}) {
+		const {onDataChanged, data: {featureGroupsIds}, isReadOnlyMode} = this.props;
+		return (
+			<ListEditorViewItem
+				key={id}
+				onDelete={() => onDataChanged({featureGroupsIds: featureGroupsIds.filter(featureGroupId => featureGroupId !== id)})}
+				isReadOnlyMode={isReadOnlyMode}>
+				<div className='name'>{name}</div>
+				<div className='inner-objects-count'>{
+					i18n(
+						'Entitlement Pools({entitlementPoolsCounter}), License Key Groups({licenseKeyGroupsCount})',
+						{
+							entitlementPoolsCounter: entitlementPoolsIds.length,
+							licenseKeyGroupsCount: licenseKeyGroupsIds.length
+						}
+					)
+				}</div>
+			</ListEditorViewItem>
+		);
+	}
+
+	filterAssociatedFeatureGroupsList(featureGroupsList) {
+		let {localFeatureGroupsListFilter} = this.state;
+		if (localFeatureGroupsListFilter) {
+			const filter = new RegExp(escape(localFeatureGroupsListFilter), 'i');
+			return featureGroupsList.filter(({name}) => name.match(filter));
+		}
+		else {
+			return featureGroupsList;
+		}
+	}
+}
+
+export default LicenseAgreementEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js
new file mode 100644
index 0000000..ca18bfa
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+import LicenseAgreementActionHelper from './LicenseAgreementActionHelper.js';
+import LicenseAgreementListEditorView from './LicenseAgreementListEditorView.jsx';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+
+const mapStateToProps = ({licenseModel: {licenseAgreement, licenseModelEditor}}) => {
+	let {licenseAgreementList} = licenseAgreement;
+	let {data} = licenseAgreement.licenseAgreementEditor;
+	let {vendorName} = licenseModelEditor.data;
+
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data);
+
+	return {
+		vendorName,
+		licenseAgreementList,
+		isReadOnlyMode,
+		isDisplayModal: Boolean(data),
+		isModalInEditMode: Boolean(data && data.id)
+	};
+};
+
+const mapActionsToProps = (dispatch, {licenseModelId}) => {
+	return {
+		onAddLicenseAgreementClick: () => LicenseAgreementActionHelper.openLicenseAgreementEditor(dispatch, {licenseModelId}),
+		onEditLicenseAgreementClick: licenseAgreement => LicenseAgreementActionHelper.openLicenseAgreementEditor(dispatch, {licenseModelId, licenseAgreement}),
+		onDeleteLicenseAgreement: licenseAgreement => LicenseAgreementActionHelper.openDeleteLicenseAgreementConfirm(dispatch, {licenseAgreement}),
+		onCallVCAction: action => {
+			LicenseModelActionHelper.performVCAction(dispatch, {licenseModelId, action}).then(() => {
+				LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId});
+			});
+		},
+		switchLicenseModelVersion: version => LicenseAgreementActionHelper.switchVersion(dispatch, {licenseModelId, version}),
+		onClose: () => OnboardingActionHelper.navigateToOnboardingCatalog(dispatch)
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(LicenseAgreementListEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx
new file mode 100644
index 0000000..4d7e704
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx
@@ -0,0 +1,126 @@
+import React from 'react';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import LicenseAgreementEditor from './LicenseAgreementEditor.js';
+import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+import {optionsInputValues} from './LicenseAgreementConstants';
+import LicenseAgreementConfirmationModal from './LicenseAgreementConfirmationModal.jsx';
+
+
+class LicenseAgreementListEditorView extends React.Component {
+	static propTypes = {
+		vendorName: React.PropTypes.string,
+		licenseModelId: React.PropTypes.string.isRequired,
+		licenseAgreementList: React.PropTypes.array,
+		isReadOnlyMode: React.PropTypes.bool.isRequired,
+		isDisplayModal: React.PropTypes.bool,
+		isModalInEditMode: React.PropTypes.bool,
+		onAddLicenseAgreementClick: React.PropTypes.func,
+		onEditLicenseAgreementClick: React.PropTypes.func,
+		onDeleteLicenseAgreement: React.PropTypes.func,
+		onCallVCAction: React.PropTypes.func
+	};
+
+	static defaultProps = {
+		licenseAgreementList: []
+	};
+
+	state = {
+		localFilter: ''
+	};
+
+	render() {
+		const {licenseModelId, vendorName, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
+		const {onAddLicenseAgreementClick} = this.props;
+		const {localFilter} = this.state;
+
+		return (
+			<div className='license-agreement-list-editor'>
+					<ListEditorView
+						title={i18n('License Agreements for {vendorName} License Model', {vendorName})}
+						plusButtonTitle={i18n('Add License Agreement')}
+						onAdd={onAddLicenseAgreementClick}
+						filterValue={localFilter}
+						onFilter={filter => this.setState({localFilter: filter})}
+						isReadOnlyMode={isReadOnlyMode}>
+						{this.filterList().map(licenseAgreement => this.renderLicenseAgreementListItem(licenseAgreement, isReadOnlyMode))}
+					</ListEditorView>
+				<Modal show={isDisplayModal} bsSize='large' animation={true} className='license-agreement-modal'>
+					<Modal.Header>
+						<Modal.Title>{`${isModalInEditMode ? i18n('Edit License Agreement') : i18n('Create New License Agreement')}`}</Modal.Title>
+					</Modal.Header>
+					<Modal.Body>
+						{
+							isDisplayModal && (
+								<LicenseAgreementEditor licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode} />
+							)
+						}
+					</Modal.Body>
+				</Modal>
+				<LicenseAgreementConfirmationModal licenseModelId={licenseModelId}/>
+
+			</div>
+		);
+	}
+
+	filterList() {
+		let {licenseAgreementList} = this.props;
+		let {localFilter} = this.state;
+		if (localFilter.trim()) {
+			const filter = new RegExp(escape(localFilter), 'i');
+			return licenseAgreementList.filter(({name = '', description = '', licenseTerm = ''}) => {
+				return escape(name).match(filter) || escape(description).match(filter) || escape(this.extractValue(licenseTerm)).match(filter);
+			});
+		}
+		else {
+			return licenseAgreementList;
+		}
+	}
+
+	renderLicenseAgreementListItem(licenseAgreement, isReadOnlyMode) {
+		let {id, name, description, licenseTerm, featureGroupsIds = []} = licenseAgreement;
+		let {onEditLicenseAgreementClick, onDeleteLicenseAgreement} = this.props;
+		return (
+			<ListEditorItemView
+				key={id}
+				onSelect={() => onEditLicenseAgreementClick(licenseAgreement)}
+				onDelete={() => onDeleteLicenseAgreement(licenseAgreement)}
+				className='list-editor-item-view'
+				isReadOnlyMode={isReadOnlyMode}>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Name')}</div>
+					<div className='text name'>{name}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='list-editor-item-view-field-tight'>
+						<div className='title'>{i18n('Type')}</div>
+						<div className='text type'>{this.extractValue(licenseTerm)}</div>
+					</div>
+					<div className='list-editor-item-view-field-tight'>
+						<div className='title'>{i18n('Feature')}</div>
+						<div className='title'>{i18n('Groups')}</div>
+						<div className='feature-groups-count'>{featureGroupsIds.length}</div>
+					</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Description')}</div>
+					<div className='text description'>{description}</div>
+				</div>
+			</ListEditorItemView>
+		);
+	}
+
+	extractValue(item) {
+		if (item === undefined) {
+			return '';
+		} //TODO fix it later
+
+		return item ? item.choice === optionInputOther.OTHER ? item.other : InputOptions.getTitleByName(optionsInputValues, item.choice) : '';
+	}
+}
+
+export default LicenseAgreementListEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListReducer.js
new file mode 100644
index 0000000..5b5fa00
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListReducer.js
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes as licenseAgreementActionTypes} from './LicenseAgreementConstants';
+
+export default (state = [], action) => {
+	switch (action.type) {
+		case licenseAgreementActionTypes.LICENSE_AGREEMENT_LIST_LOADED:
+			return [...action.response.results];
+		case licenseAgreementActionTypes.ADD_LICENSE_AGREEMENT:
+			return [...state, action.licenseAgreement];
+		case licenseAgreementActionTypes.EDIT_LICENSE_AGREEMENT:
+			const indexForEdit = state.findIndex(licenseAgreement => licenseAgreement.id === action.licenseAgreement.id);
+			return [...state.slice(0, indexForEdit), action.licenseAgreement, ...state.slice(indexForEdit + 1)];
+		case licenseAgreementActionTypes.DELETE_LICENSE_AGREEMENT:
+			return state.filter(licenseAgreement => licenseAgreement.id !== action.licenseAgreementId);
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js
new file mode 100644
index 0000000..50ac2c8
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js
@@ -0,0 +1,139 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import {actionTypes as licenseKeyGroupsConstants} from './LicenseKeyGroupsConstants.js';
+import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+
+function baseUrl(licenseModelId) {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/license-key-groups`;
+}
+
+function fetchLicenseKeyGroupsList(licenseModelId, version) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(licenseModelId)}${versionQuery}`);
+}
+
+function deleteLicenseKeyGroup(licenseModelId, licenseKeyGroupId) {
+	return RestAPIUtil.destroy(`${baseUrl(licenseModelId)}/${licenseKeyGroupId}`);
+}
+
+function postLicenseKeyGroup(licenseModelId, licenseKeyGroup) {
+	return RestAPIUtil.create(baseUrl(licenseModelId), {
+		name: licenseKeyGroup.name,
+		description: licenseKeyGroup.description,
+		operationalScope: licenseKeyGroup.operationalScope,
+		type: licenseKeyGroup.type
+	});
+}
+
+function putLicenseKeyGroup(licenseModelId, licenseKeyGroup) {
+	return RestAPIUtil.save(`${baseUrl(licenseModelId)}/${licenseKeyGroup.id}`, {
+		name: licenseKeyGroup.name,
+		description: licenseKeyGroup.description,
+		operationalScope: licenseKeyGroup.operationalScope,
+		type: licenseKeyGroup.type
+	});
+}
+
+
+export default {
+	fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}) {
+		return fetchLicenseKeyGroupsList(licenseModelId, version).then(response => dispatch({
+			type: licenseKeyGroupsConstants.LICENSE_KEY_GROUPS_LIST_LOADED,
+			response
+		}));
+	},
+
+	openLicenseKeyGroupsEditor(dispatch, {licenseKeyGroup} = {}) {
+		dispatch({
+			type: licenseKeyGroupsConstants.licenseKeyGroupsEditor.OPEN,
+			licenseKeyGroup
+		});
+	},
+
+	closeLicenseKeyGroupEditor(dispatch){
+		dispatch({
+			type: licenseKeyGroupsConstants.licenseKeyGroupsEditor.CLOSE
+		});
+	},
+
+	saveLicenseKeyGroup(dispatch, {licenseModelId, previousLicenseKeyGroup, licenseKeyGroup}) {
+		if (previousLicenseKeyGroup) {
+			return putLicenseKeyGroup(licenseModelId, licenseKeyGroup).then(() => {
+				dispatch({
+					type: licenseKeyGroupsConstants.EDIT_LICENSE_KEY_GROUP,
+					licenseKeyGroup
+				});
+			});
+		}
+		else {
+			return postLicenseKeyGroup(licenseModelId, licenseKeyGroup).then(response => {
+				dispatch({
+					type: licenseKeyGroupsConstants.ADD_LICENSE_KEY_GROUP,
+					licenseKeyGroup: {
+						...licenseKeyGroup,
+						id: response.value
+					}
+				});
+			});
+		}
+
+
+	},
+
+	deleteLicenseKeyGroup(dispatch, {licenseModelId, licenseKeyGroupId}){
+		return deleteLicenseKeyGroup(licenseModelId, licenseKeyGroupId).then(()=> {
+			dispatch({
+				type: licenseKeyGroupsConstants.DELETE_LICENSE_KEY_GROUP,
+				licenseKeyGroupId
+			});
+		});
+	},
+
+	licenseKeyGroupEditorDataChanged(dispatch, {deltaData}) {
+		dispatch({
+			type: licenseKeyGroupsConstants.licenseKeyGroupsEditor.DATA_CHANGED,
+			deltaData
+		});
+	},
+
+	hideDeleteConfirm(dispatch) {
+		dispatch({
+			type: licenseKeyGroupsConstants.LICENSE_KEY_GROUPS_DELETE_CONFIRM,
+			licenseKeyGroupToDelete: false
+		});
+	},
+
+	openDeleteLicenseAgreementConfirm(dispatch, {licenseKeyGroup}) {
+		dispatch({
+			type: licenseKeyGroupsConstants.LICENSE_KEY_GROUPS_DELETE_CONFIRM,
+			licenseKeyGroupToDelete: licenseKeyGroup
+		});
+	},
+
+	switchVersion(dispatch, {licenseModelId, version}) {
+		LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
+			this.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version});
+		});
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConfirmationModal.jsx
new file mode 100644
index 0000000..2413db5
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConfirmationModal.jsx
@@ -0,0 +1,49 @@
+import React from 'react';
+import {connect} from 'react-redux';
+import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
+import LicenseKeyGroupsActionHelper from './LicenseKeyGroupsActionHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+function renderMsg(licenseKeyGroupToDelete) {
+	let name = licenseKeyGroupToDelete ? licenseKeyGroupToDelete.name : '';
+	let msg = i18n('Are you sure you want to delete "{name}"?', {name});
+	let subMsg =  licenseKeyGroupToDelete
+					&& licenseKeyGroupToDelete.referencingFeatureGroups
+					&& licenseKeyGroupToDelete.referencingFeatureGroups.length > 0 ?
+					i18n('This license key group is associated with one or more feature groups') :
+					'';
+	return(
+		<div>
+			<p>{msg}</p>
+			<p>{subMsg}</p>
+		</div>
+	);
+};
+
+const mapStateToProps = ({licenseModel: {licenseKeyGroup}}, {licenseModelId}) => {
+	let {licenseKeyGroupToDelete} = licenseKeyGroup;
+	const show = licenseKeyGroupToDelete !== false;
+	return {
+		show,
+		title: 'Warning!',
+		type: 'warning',
+		msg: renderMsg(licenseKeyGroupToDelete),
+		confirmationDetails: {licenseKeyGroupToDelete, licenseModelId}
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onConfirmed: ({licenseKeyGroupToDelete, licenseModelId}) => {
+
+			LicenseKeyGroupsActionHelper.deleteLicenseKeyGroup(dispatch, {licenseModelId, licenseKeyGroupId:licenseKeyGroupToDelete.id});
+			LicenseKeyGroupsActionHelper.hideDeleteConfirm(dispatch);
+		},
+		onDeclined: () => {
+			LicenseKeyGroupsActionHelper.hideDeleteConfirm(dispatch);
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js
new file mode 100644
index 0000000..d32bc52
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+export const actionTypes = keyMirror({
+
+	LICENSE_KEY_GROUPS_LIST_LOADED: null,
+	DELETE_LICENSE_KEY_GROUP: null,
+	EDIT_LICENSE_KEY_GROUP: null,
+	ADD_LICENSE_KEY_GROUP: null,
+	LICENSE_KEY_GROUPS_DELETE_CONFIRM: null,
+	licenseKeyGroupsEditor: {
+		OPEN: null,
+		CLOSE: null,
+		DATA_CHANGED: null,
+	}
+});
+
+export const defaultState = {
+	licenseKeyGroupsEditor: {
+		type: '',
+		operationalScope: {choices: [], other: ''}
+	}
+};
+
+export const optionsInputValues = {
+	OPERATIONAL_SCOPE: [
+		{enum: '', title: i18n('please select…')},
+		{enum: 'Network_Wide', title: 'Network Wide'},
+		{enum: 'Availability_Zone', title: 'Availability Zone'},
+		{enum: 'Data_Center', title: 'Data Center'},
+		{enum: 'Tenant', title: 'Tenant'},
+		{enum: 'VM', title: 'VM'},
+		{enum: 'CPU', title: 'CPU'},
+		{enum: 'Core', title: 'Core'}
+	],
+	TYPE: [
+		{enum: '', title: i18n('please select…')},
+		{enum: 'Universal', title: 'Universal'},
+		{enum: 'Unique', title: 'Unique'},
+		{enum: 'One_Time', title: 'One Time'}
+	]
+};
+
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js
new file mode 100644
index 0000000..3940ec5
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import LicenseKeyGroupsActionHelper from './LicenseKeyGroupsActionHelper.js';
+import LicenseKeyGroupsEditorView from './LicenseKeyGroupsEditorView.jsx';
+
+const mapStateToProps = ({licenseModel: {licenseKeyGroup}}) => {
+
+
+	let {data} = licenseKeyGroup.licenseKeyGroupsEditor;
+
+	let previousData;
+	const licenseKeyGroupId = data ? data.id : null;
+	if(licenseKeyGroupId) {
+		previousData = licenseKeyGroup.licenseKeyGroupsList.find(licenseKeyGroup => licenseKeyGroup.id === licenseKeyGroupId);
+	}
+
+	return {
+		data,
+		previousData
+	};
+};
+
+const mapActionsToProps = (dispatch, {licenseModelId}) => {
+	return {
+		onDataChanged: deltaData => LicenseKeyGroupsActionHelper.licenseKeyGroupEditorDataChanged(dispatch, {deltaData}),
+		onCancel: () => LicenseKeyGroupsActionHelper.closeLicenseKeyGroupEditor(dispatch),
+		onSubmit: ({previousLicenseKeyGroup, licenseKeyGroup}) => {
+			LicenseKeyGroupsActionHelper.closeLicenseKeyGroupEditor(dispatch);
+			LicenseKeyGroupsActionHelper.saveLicenseKeyGroup(dispatch, {licenseModelId, previousLicenseKeyGroup, licenseKeyGroup});
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(LicenseKeyGroupsEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js
new file mode 100644
index 0000000..a744982
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes, defaultState} from './LicenseKeyGroupsConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.licenseKeyGroupsEditor.OPEN:
+			return {
+				...state,
+				data: action.licenseKeyGroup ? {...action.licenseKeyGroup} : defaultState.licenseKeyGroupsEditor
+			};
+		case actionTypes.licenseKeyGroupsEditor.CLOSE:
+			return {};
+		case actionTypes.licenseKeyGroupsEditor.DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx
new file mode 100644
index 0000000..102e713
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx
@@ -0,0 +1,92 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import {optionsInputValues as licenseKeyGroupOptionsInputValues} from './LicenseKeyGroupsConstants.js';
+import {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+
+const LicenseKeyGroupPropType = React.PropTypes.shape({
+	id: React.PropTypes.string,
+	name: React.PropTypes.string,
+	description: React.PropTypes.string,
+	operationalScope: React.PropTypes.shape({
+		choices: React.PropTypes.array,
+		other: React.PropTypes.string
+	}),
+	type: React.PropTypes.string
+});
+
+class LicenseKeyGroupsEditorView extends React.Component {
+	static propTypes = {
+		data: LicenseKeyGroupPropType,
+		previousData: LicenseKeyGroupPropType,
+		isReadOnlyMode: React.PropTypes.bool,
+		onDataChanged: React.PropTypes.func.isRequired,
+		onSubmit: React.PropTypes.func.isRequired,
+		onCancel: React.PropTypes.func.isRequired
+	};
+
+	static defaultProps = {
+		data: {}
+	};
+
+	render() {
+		let {data = {}, onDataChanged, isReadOnlyMode} = this.props;
+		let {name, description, operationalScope, type} = data;
+		return (
+			<ValidationForm
+				ref='validationForm'
+				hasButtons={true}
+				onSubmit={ () => this.submit() }
+				onReset={ () => this.props.onCancel() }
+				labledButtons={true}
+				isReadOnlyMode={isReadOnlyMode}
+				className='license-key-groups-form'>
+				<div className='license-key-groups-form-row'>
+					<ValidationInput
+						onChange={name => onDataChanged({name})}
+						ref='name'
+						label={i18n('Name')}
+						value={name}
+						validations={{maxLength: 120, required: true}}
+						type='text'/>
+					<ValidationInput
+						isMultiSelect={true}
+						isRequired={true}
+						onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}})}
+						onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER], other: operationalScope}})}
+						label={i18n('Operational Scope')}
+						validations={{required: true}}
+						multiSelectedEnum={operationalScope && operationalScope.choices}
+						otherValue={operationalScope && operationalScope.other}
+						values={licenseKeyGroupOptionsInputValues.OPERATIONAL_SCOPE}/>
+				</div>
+				<div className='license-key-groups-form-row'>
+					<ValidationInput
+						onChange={description => onDataChanged({description})}
+						ref='description'
+						label={i18n('Description')}
+						value={description}
+						validations={{maxLength: 1000, required: true}}
+						type='textarea'/>
+						<ValidationInput
+							isRequired={true}
+							onEnumChange={type => onDataChanged({type})}
+							selectedEnum={type}
+							label={i18n('Type')}
+							type='select'
+							validations={{required: true}}
+							values={licenseKeyGroupOptionsInputValues.TYPE}/>
+					</div>
+			</ValidationForm>
+		);
+	}
+
+	submit() {
+		const {data: licenseKeyGroup, previousData: previousLicenseKeyGroup} = this.props;
+		this.props.onSubmit({licenseKeyGroup, previousLicenseKeyGroup});
+	}
+}
+
+export default LicenseKeyGroupsEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js
new file mode 100644
index 0000000..e1b610f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import LicenseKeyGroupsActionHelper from './LicenseKeyGroupsActionHelper.js';
+import LicenseKeyGroupsListEditorView from './LicenseKeyGroupsListEditorView.jsx';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+const mapStateToProps = ({licenseModel: {licenseKeyGroup, licenseModelEditor}}) => {
+	let {licenseKeyGroupsList} = licenseKeyGroup;
+	let {data} = licenseKeyGroup.licenseKeyGroupsEditor;
+	let {vendorName} = licenseModelEditor.data;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data);
+
+	return {
+		vendorName,
+		licenseKeyGroupsList,
+		isReadOnlyMode,
+		isDisplayModal: Boolean(data),
+		isModalInEditMode: Boolean(data && data.id)
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onAddLicenseKeyGroupClick: () => LicenseKeyGroupsActionHelper.openLicenseKeyGroupsEditor(dispatch),
+		onEditLicenseKeyGroupClick: licenseKeyGroup => LicenseKeyGroupsActionHelper.openLicenseKeyGroupsEditor(dispatch, {licenseKeyGroup}),
+		onDeleteLicenseKeyGroupClick: licenseKeyGroup => LicenseKeyGroupsActionHelper.openDeleteLicenseAgreementConfirm(dispatch, {licenseKeyGroup})
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(LicenseKeyGroupsListEditorView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx
new file mode 100644
index 0000000..1ed1d20
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx
@@ -0,0 +1,138 @@
+import React from 'react';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+
+import LicenseKeyGroupsEditor from './LicenseKeyGroupsEditor.js';
+import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+import {optionsInputValues} from './LicenseKeyGroupsConstants';
+import LicenseKeyGroupsConfirmationModal from './LicenseKeyGroupsConfirmationModal.jsx';
+
+
+class LicenseKeyGroupsListEditorView extends React.Component {
+	static propTypes = {
+		vendorName: React.PropTypes.string,
+		licenseModelId: React.PropTypes.string.isRequired,
+		licenseKeyGroupsList: React.PropTypes.array,
+		isReadOnlyMode: React.PropTypes.bool.isRequired,
+		isDisplayModal: React.PropTypes.bool,
+		isModalInEditMode: React.PropTypes.bool,
+		onAddLicenseKeyGroupClick: React.PropTypes.func,
+		onEditLicenseKeyGroupClick: React.PropTypes.func,
+		onDeleteLicenseKeyGroupClick: React.PropTypes.func
+	};
+
+	static defaultProps = {
+		licenseKeyGroupsList: []
+	};
+
+	state = {
+		localFilter: ''
+	};
+
+	render() {
+		let {licenseModelId, vendorName, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
+		let {onAddLicenseKeyGroupClick} = this.props;
+		const {localFilter} = this.state;
+
+		return (
+			<div className='license-key-groups-list-editor'>
+				<ListEditorView
+					title={i18n('License Key Groups for {vendorName} License Model', {vendorName})}
+					plusButtonTitle={i18n('Add License Key Group')}
+					onAdd={onAddLicenseKeyGroupClick}
+					filterValue={localFilter}
+					onFilter={filter => this.setState({localFilter: filter})}
+					isReadOnlyMode={isReadOnlyMode}>
+					{this.filterList().map(licenseKeyGroup => (this.renderLicenseKeyGroupListItem(licenseKeyGroup, isReadOnlyMode)))}
+				</ListEditorView>
+				<Modal show={isDisplayModal} bsSize='large' animation={true} className='license-key-groups-modal'>
+					<Modal.Header>
+						<Modal.Title>{`${isModalInEditMode ? i18n('Edit License Key Group') : i18n('Create New License Key Group')}`}</Modal.Title>
+					</Modal.Header>
+					<Modal.Body>
+						{
+							isDisplayModal && (
+								<LicenseKeyGroupsEditor licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>
+							)
+						}
+					</Modal.Body>
+				</Modal>
+				<LicenseKeyGroupsConfirmationModal licenseModelId={licenseModelId}/>
+
+			</div>
+		);
+	}
+
+	filterList() {
+		let {licenseKeyGroupsList} = this.props;
+		let {localFilter} = this.state;
+		if (localFilter.trim()) {
+			const filter = new RegExp(escape(localFilter), 'i');
+			return licenseKeyGroupsList.filter(({name = '', description = '', operationalScope = '', type = ''}) => {
+				return escape(name).match(filter) || escape(description).match(filter) || escape(this.extractValue(operationalScope)).match(filter) || escape(type).match(filter);
+			});
+		}
+		else {
+			return licenseKeyGroupsList;
+		}
+	}
+
+	renderLicenseKeyGroupListItem(licenseKeyGroup, isReadOnlyMode) {
+		let {id, name, description, operationalScope, type} = licenseKeyGroup;
+		let {onEditLicenseKeyGroupClick, onDeleteLicenseKeyGroupClick} = this.props;
+		return (
+			<ListEditorItemView
+				key={id}
+				onSelect={() => onEditLicenseKeyGroupClick(licenseKeyGroup)}
+				onDelete={() => onDeleteLicenseKeyGroupClick(licenseKeyGroup)}
+				className='list-editor-item-view'
+				isReadOnlyMode={isReadOnlyMode}>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Name')}</div>
+					<div className='text name'>{name}</div>
+				</div>
+
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Operational Scope')}</div>
+					<div className='text operational-scope'>{operationalScope && this.getOperationalScopes(operationalScope)}</div>
+
+					<div className='title'>{i18n('Type')}</div>
+					<div className='text type'>{InputOptions.getTitleByName(optionsInputValues, type)}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Description')}</div>
+					<div className='text description'>{description}</div>
+				</div>
+			</ListEditorItemView>
+		);
+	}
+
+	getOperationalScopes(operationalScope) {
+		if(operationalScope.choices.toString() === i18n(optionInputOther.OTHER) && operationalScope.other !== '') {
+			return operationalScope.other;
+		}
+		else {
+			let allOpScopes = '';
+			for (let opScope of operationalScope.choices) {
+				allOpScopes += allOpScopes === '' ? InputOptions.getTitleByName(optionsInputValues, opScope) : `, ${InputOptions.getTitleByName(optionsInputValues, opScope)}`;
+			}
+			return allOpScopes;
+		}
+	}
+
+	extractValue(item) {
+		if (item === undefined) {
+			return '';
+		} //TODO fix it later
+
+		return item ? item.choice === optionInputOther.OTHER ? item.other : InputOptions.getTitleByName(optionsInputValues, item.choice) : '';
+	}
+}
+
+export default LicenseKeyGroupsListEditorView;
+
+
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListReducer.js
new file mode 100644
index 0000000..54ce4e3
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListReducer.js
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './LicenseKeyGroupsConstants.js';
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.LICENSE_KEY_GROUPS_LIST_LOADED:
+			return [...action.response.results];
+		case actionTypes.DELETE_LICENSE_KEY_GROUP:
+			return state.filter(licenseKeyGroup => licenseKeyGroup.id !== action.licenseKeyGroupId);
+		case actionTypes.ADD_LICENSE_KEY_GROUP:
+			return [...state, action.licenseKeyGroup];
+		case actionTypes.EDIT_LICENSE_KEY_GROUP:
+			const indexForEdit = state.findIndex(licenseKeyGroup => licenseKeyGroup.id === action.licenseKeyGroup.id);
+			return [...state.slice(0, indexForEdit), action.licenseKeyGroup, ...state.slice(indexForEdit + 1)];
+		default:
+			return state;
+	}
+};
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js
new file mode 100644
index 0000000..2dbef6b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js
@@ -0,0 +1,321 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import TabulatedEditor from 'src/nfvo-components/editor/TabulatedEditor.jsx';
+
+import {enums} from 'sdc-app/onboarding/OnboardingConstants.js';
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+
+import {navigationItems} from './SoftwareProductConstants.js';
+import SoftwareProductActionHelper from './SoftwareProductActionHelper.js';
+import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js';
+
+const buildComponentNavigationBarGroups = ({componentId, meta}) => {
+	const groups = ([
+		{
+			id: navigationItems.GENERAL + '|' + componentId,
+			name: i18n('General'),
+			disabled: false,
+			meta
+		}, {
+			id: navigationItems.COMPUTE + '|' + componentId,
+			name: i18n('Compute'),
+			disabled: false,
+			meta
+		}, {
+			id: navigationItems.LOAD_BALANCING + '|' + componentId,
+			name: i18n('High Availability & Load Balancing'),
+			disabled: false,
+			meta
+		}, {
+			id: navigationItems.NETWORKS + '|' + componentId,
+			name: i18n('Networks'),
+			disabled: false,
+			meta
+		}, {
+			id: navigationItems.STORAGE + '|' + componentId,
+			name: i18n('Storage'),
+			disabled: false,
+			meta
+		}, {
+			id: navigationItems.PROCESS_DETAILS + '|' + componentId,
+			name: i18n('Process Details'),
+			disabled: false,
+			meta
+		}, {
+			id: navigationItems.MONITORING + '|' + componentId,
+			name: i18n('Monitoring'),
+			disabled: false,
+			meta
+		}
+	]);
+
+	return groups;
+};
+
+const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}) => {
+	const {softwareProductEditor: {data: currentSoftwareProduct = {}}} = softwareProduct;
+	const {id, name} = currentSoftwareProduct;
+	const groups = [{
+		id: id,
+		name: name,
+		items: [
+			{
+				id: navigationItems.VENDOR_SOFTWARE_PRODUCT,
+				name: i18n('Overview'),
+				disabled: false,
+				meta
+			}, {
+				id: navigationItems.GENERAL,
+				name: i18n('General'),
+				disabled: false,
+				meta
+			}, {
+				id: navigationItems.PROCESS_DETAILS,
+				name: i18n('Process Details'),
+				disabled: false,
+				meta
+			}, {
+				id: navigationItems.NETWORKS,
+				name: i18n('Networks'),
+				disabled: false,
+				meta
+			}, {
+				id: navigationItems.ATTACHMENTS,
+				name: i18n('Attachments'),
+				disabled: false,
+				meta
+			}, {
+				id: navigationItems.COMPONENTS,
+				name: i18n('Components'),
+				hidden: componentsList.length <= 0,
+				meta,
+				expanded: mapOfExpandedIds[navigationItems.COMPONENTS] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
+				items: [
+					...componentsList.map(({id, displayName}) => ({
+						id: navigationItems.COMPONENTS + '|' + id,
+						name: displayName,
+						meta,
+						expanded: mapOfExpandedIds[navigationItems.COMPONENTS + '|' + id] === true  && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
+						items: buildComponentNavigationBarGroups({componentId: id, meta})
+					}))
+				]
+			}
+		]
+	}];
+	let activeItemId = ({
+		[enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE]: navigationItems.VENDOR_SOFTWARE_PRODUCT,
+		[enums.SCREEN.SOFTWARE_PRODUCT_DETAILS]: navigationItems.GENERAL,
+		[enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS]: navigationItems.ATTACHMENTS,
+		[enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES]: navigationItems.PROCESS_DETAILS,
+		[enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS]: navigationItems.NETWORKS,
+		[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: navigationItems.COMPONENTS
+	})[screen];
+
+	if(componentId) {
+		activeItemId =
+			Object.keys(mapOfExpandedIds).length === 1 && mapOfExpandedIds[navigationItems.COMPONENTS] === true ?
+			navigationItems.COMPONENTS : ({
+				[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL]: navigationItems.GENERAL,
+				[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE]: navigationItems.COMPUTE,
+				[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING]: navigationItems.LOAD_BALANCING,
+				[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK]: navigationItems.NETWORKS,
+				[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE]: navigationItems.STORAGE,
+				[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES]: navigationItems.PROCESS_DETAILS,
+				[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING]: navigationItems.MONITORING
+			})[screen] + '|' + componentId;
+	}
+
+	return {
+		activeItemId, groups
+	};
+};
+
+const buildVersionControllerProps = (softwareProduct) => {
+	const {softwareProductEditor} = softwareProduct;
+	const {data: currentSoftwareProduct = {}, isValidityData = true} = softwareProductEditor;
+
+	const {version, viewableVersions, status: currentStatus, lockingUser} = currentSoftwareProduct;
+	const {status, isCheckedOut} = (currentStatus === versionStatusEnum.CHECK_OUT_STATUS) ?
+		VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser) :
+		{status: currentStatus, isCheckedOut: false};
+
+	return {
+		status, isCheckedOut, version, viewableVersions,
+		isFormDataValid: isValidityData
+	};
+};
+
+const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => {
+	const {softwareProductEditor, softwareProductComponents, softwareProductQuestionnaire} = softwareProduct;
+	const {data: currentSoftwareProduct = {}, mapOfExpandedIds = []} = softwareProductEditor;
+	const {version} = currentSoftwareProduct;
+	const {componentsList = []} = softwareProductComponents;
+	const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+	const {qdata} = softwareProductQuestionnaire;
+	let currentComponentMeta = {};
+	if(componentId) {
+		const {componentEditor: {data: componentData = {} , qdata: componentQdata}} = softwareProductComponents;
+		currentComponentMeta = {componentData, componentQdata};
+	}
+	const meta = {softwareProduct: currentSoftwareProduct, qdata, version, isReadOnlyMode, currentComponentMeta};
+	return {
+		versionControllerProps: buildVersionControllerProps(softwareProduct),
+		navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds})
+	};
+};
+
+const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId, meta: {isReadOnlyMode, softwareProduct, qdata, currentComponentMeta: {componentData, componentQdata}}}) => {
+	let promise;
+	if (isReadOnlyMode) {
+		promise = Promise.resolve();
+	} else {
+		switch(screen) {
+			case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS:
+				promise = SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});
+				break;
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
+				promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId: componentId, componentData, qdata: componentQdata});
+				break;
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
+			case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
+				promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata: componentQdata});
+				break;
+			default:
+				promise = Promise.resolve();
+				break;
+		}
+	}
+	return promise;
+};
+
+
+const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentComponentId}) => {
+	const [nextScreen, nextComponentId] = id.split('|');
+	switch(nextScreen) {
+		case navigationItems.COMPONENTS:
+			if(nextComponentId === currentComponentId) {
+				OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId});
+			} else {
+				OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version});
+			}
+			break;
+		case navigationItems.GENERAL:
+			OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version});
+			break;
+		case navigationItems.COMPUTE:
+			OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId: nextComponentId});
+			break;
+		case navigationItems.LOAD_BALANCING:
+			OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId: nextComponentId});
+			break;
+		case navigationItems.NETWORKS:
+			OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId: nextComponentId, version});
+			break;
+		case navigationItems.STORAGE:
+			OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId: nextComponentId});
+			break;
+		case navigationItems.PROCESS_DETAILS:
+			OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId: nextComponentId});
+			break;
+		case navigationItems.MONITORING:
+			OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId: nextComponentId});
+			break;
+	}
+};
+
+const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwareProductId, componentId: currentComponentId}}}) => {
+
+	const props = {
+		onClose: ({version}) => {
+			if (screen === enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE) {
+				OnboardingActionHelper.navigateToOnboardingCatalog(dispatch);
+			} else {
+				OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version});
+			}
+		},
+		onVersionSwitching: (version) => {
+			OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version});
+		},
+		onToggle: (groups, itemIdToExpand) => groups.map(({items}) => SoftwareProductActionHelper.toggleNavigationItems(dispatch, {items, itemIdToExpand})),
+		onNavigate: ({id, meta}) => {
+			let preNavigate = autoSaveBeforeNavigate({dispatch, screen, meta, softwareProductId, componentId: currentComponentId});
+			preNavigate.then(() => {
+				switch(id) {
+					case navigationItems.VENDOR_SOFTWARE_PRODUCT:
+						OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: meta.version});
+						break;
+					case navigationItems.GENERAL:
+						OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId});
+						break;
+					case navigationItems.PROCESS_DETAILS:
+						OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version: meta.version});
+						break;
+					case navigationItems.NETWORKS:
+						OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version: meta.version});
+						break;
+					case navigationItems.ATTACHMENTS:
+						OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId});
+						break;
+					case navigationItems.COMPONENTS:
+						OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId});
+						break;
+					default:
+						onComponentNavigate(dispatch, {id, softwareProductId, version: meta.version, screen, currentComponentId});
+						break;
+				}
+			});
+		}
+	};
+
+	switch (screen) {
+		case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE:
+		case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
+		case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
+		case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
+		case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
+		case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
+		case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
+			props.onSave = () => {
+				return Promise.resolve();
+			};
+			break;
+		default:
+			props.onSave = ({softwareProduct, qdata}) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});
+			break;
+	}
+
+
+	props.onVersionControllerAction = (action) =>
+		SoftwareProductActionHelper.performVCAction(dispatch, {softwareProductId, action}).then(() => {
+			SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId});
+		});
+
+	return props;
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(TabulatedEditor);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js
new file mode 100644
index 0000000..d9ed8af
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js
@@ -0,0 +1,333 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+import LicenseAgreementActionHelper from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js';
+import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js';
+
+import {actionTypes} from './SoftwareProductConstants.js';
+import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js';
+import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+
+function baseUrl() {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-software-products/`;
+}
+function softwareProductCategoriesUrl() {
+	const restATTPrefix = Configuration.get('restATTPrefix');
+	return `${restATTPrefix}/v1/categories/resources/`;
+}
+
+function uploadFile(vspId, formData) {
+
+	return RestAPIUtil.create(`${baseUrl()}${vspId}/upload`, formData);
+
+}
+
+function putSoftwareProduct(softwareData) {
+	return RestAPIUtil.save(`${baseUrl()}${softwareData.id}`, {
+		name: softwareData.name,
+		description: softwareData.description,
+		category: softwareData.category,
+		subCategory: softwareData.subCategory,
+		vendorId: softwareData.vendorId,
+		vendorName: softwareData.vendorName,
+		licensingVersion: softwareData.licensingVersion,
+		icon: softwareData.icon,
+		licensingData: softwareData.licensingData
+	});
+}
+
+function putSoftwareProductQuestionnaire(vspId, qdata) {
+	return RestAPIUtil.save(`${baseUrl()}${vspId}/questionnaire`, qdata);
+}
+
+function putSoftwareProductAction(id, action) {
+	return RestAPIUtil.save(`${baseUrl()}${id}/actions`, {action: action});
+}
+
+function fetchSoftwareProductList() {
+	return RestAPIUtil.fetch(baseUrl());
+}
+
+function fetchSoftwareProduct(vspId, version) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl()}${vspId}${versionQuery}`);
+}
+
+function fetchSoftwareProductQuestionnaire(vspId, version) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl()}${vspId}/questionnaire${versionQuery}`);
+}
+
+function objToString(obj) {
+	let str = '';
+	if (obj instanceof Array) {
+		obj.forEach((item) => {
+			str += objToString(item) + '\n';
+		});
+	} else {
+		for (let p in obj) {
+			if (obj.hasOwnProperty(p)) {
+				str += obj[p] + '\n';
+			}
+		}
+	}
+	return str;
+}
+
+function parseUploadErrorMsg(error) {
+	let message = '';
+	for (let key in error) {
+		if (error.hasOwnProperty(key)) {
+			message += objToString(error[key]) + '\n';
+		}
+	}
+	return message;
+}
+
+function fetchSoftwareProductCategories(dispatch) {
+	let handleResponse = response => dispatch({
+		type: actionTypes.SOFTWARE_PRODUCT_CATEGORIES_LOADED,
+		softwareProductCategories: response
+	});
+	return RestAPIUtil.fetch(softwareProductCategoriesUrl())
+		.then(handleResponse)
+		.fail(() => handleResponse(null));
+}
+
+function loadLicensingData(dispatch, {licenseModelId, licensingVersion}) {
+	LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: licensingVersion});
+	FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: licensingVersion});
+}
+
+function getExpandedItemsId(items, itemIdToToggle) {
+	for(let i = 0; i < items.length; i++) {
+		if(items[i].id === itemIdToToggle) {
+			if (items[i].expanded) {
+				return {};
+			} else {
+				return {[itemIdToToggle]: true};
+			}
+		}
+		else if(items[i].items && items[i].items.length > 0) {
+			let mapOfExpandedIds = getExpandedItemsId(items[i].items, itemIdToToggle);
+			if (mapOfExpandedIds !== false) {
+				mapOfExpandedIds[items[i].id] = true;
+				return mapOfExpandedIds;
+			}
+		}
+	}
+	return false;
+}
+
+const SoftwareProductActionHelper = {
+
+	loadSoftwareProductAssociatedData(dispatch) {
+		fetchSoftwareProductCategories(dispatch);
+		LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch);
+	},
+
+	loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion}) {
+		SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch);
+		loadLicensingData(dispatch, {licenseModelId, licensingVersion});
+	},
+
+	fetchSoftwareProductList(dispatch) {
+		return fetchSoftwareProductList().then(response => dispatch({
+			type: actionTypes.SOFTWARE_PRODUCT_LIST_LOADED,
+			response
+		}));
+	},
+
+	uploadFile(dispatch, {softwareProductId, formData, failedNotificationTitle}) {
+		Promise.resolve()
+			.then(() => uploadFile(softwareProductId, formData))
+			.then(response => {
+				if (response.status !== 'Success') {
+					throw new Error(parseUploadErrorMsg(response.errors));
+				}
+			})
+			.then(() => {
+				SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId});
+				OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId});
+				SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId});
+			})
+			.catch(error => {
+				dispatch({
+					type: NotificationConstants.NOTIFY_ERROR,
+					data: {title: failedNotificationTitle, msg: error.message}
+				});
+			});
+	},
+
+	uploadConfirmation(dispatch, {softwareProductId, formData, failedNotificationTitle}) {
+		dispatch({
+			type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION,
+			uploadData: {
+				softwareProductId,
+				formData,
+				failedNotificationTitle
+			}
+		});
+	},
+	hideUploadConfirm (dispatch) {
+		dispatch({
+			type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION
+		});
+	},
+	updateSoftwareProduct(dispatch, {softwareProduct, qdata}) {
+		return Promise.all([
+			SoftwareProductActionHelper.updateSoftwareProductData(dispatch, {softwareProduct}).then(
+				() => dispatch({
+					type: actionTypes.SOFTWARE_PRODUCT_LIST_EDIT,
+					payload: {softwareProduct}
+				})
+			),
+			SoftwareProductActionHelper.updateSoftwareProductQuestionnaire(dispatch, {
+				softwareProductId: softwareProduct.id,
+				qdata
+			})
+		]);
+	},
+
+	updateSoftwareProductData(dispatch, {softwareProduct}) {
+		return putSoftwareProduct(softwareProduct);
+	},
+
+	updateSoftwareProductQuestionnaire(dispatch, {softwareProductId, qdata}) {
+		return putSoftwareProductQuestionnaire(softwareProductId, qdata);
+	},
+
+	softwareProductEditorDataChanged(dispatch, {deltaData}) {
+		dispatch({
+			type: actionTypes.softwareProductEditor.DATA_CHANGED,
+			deltaData
+		});
+	},
+
+	softwareProductQuestionnaireUpdate(dispatch, {data}) {
+		dispatch({
+			type: actionTypes.SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE,
+			payload: {qdata: data}
+		});
+	},
+
+	softwareProductEditorVendorChanged(dispatch, {deltaData}) {
+		LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId: deltaData.vendorId, version: deltaData.licensingVersion});
+		FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId: deltaData.vendorId, version: deltaData.licensingVersion});
+		SoftwareProductActionHelper.softwareProductEditorDataChanged(dispatch, {deltaData});
+	},
+
+	setIsValidityData(dispatch, {isValidityData}) {
+		dispatch({
+			type: actionTypes.softwareProductEditor.IS_VALIDITY_DATA_CHANGED,
+			isValidityData
+		});
+	},
+
+	addSoftwareProduct(dispatch, {softwareProduct}) {
+		dispatch({
+			type: actionTypes.ADD_SOFTWARE_PRODUCT,
+			softwareProduct
+		});
+	},
+
+	fetchSoftwareProduct(dispatch, {softwareProductId, version}) {
+		return Promise.all([
+			fetchSoftwareProduct(softwareProductId, version).then(response => {
+				dispatch({
+					type: actionTypes.SOFTWARE_PRODUCT_LOADED,
+					response
+				});
+				return response;
+			}),
+			fetchSoftwareProductQuestionnaire(softwareProductId, version).then(response => {
+				dispatch({
+					type: actionTypes.SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE,
+					payload: {
+						qdata: response.data ? JSON.parse(response.data) : {},
+						qschema: JSON.parse(response.schema)
+					}
+				});
+			})
+		]);
+	},
+
+	performVCAction(dispatch, {softwareProductId, action}) {
+		if (action === VersionControllerActionsEnum.SUBMIT) {
+			return putSoftwareProductAction(softwareProductId, action).then(() => {
+				return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.CREATE_PACKAGE).then(() => {
+					dispatch({
+						type: NotificationConstants.NOTIFY_SUCCESS,
+						data: {
+							title: i18n('Submit Succeeded'),
+							msg: i18n('This software product successfully submitted'),
+							timeout: 2000
+						}
+					});
+					fetchSoftwareProduct(softwareProductId).then(response => {
+						dispatch({
+							type: actionTypes.SOFTWARE_PRODUCT_LOADED,
+							response
+						});
+					});
+				});
+			}, error => dispatch({
+				type: NotificationConstants.NOTIFY_ERROR,
+				data: {title: i18n('Submit Failed'), validationResponse: error.responseJSON}
+			}));
+		}
+		else {
+			return putSoftwareProductAction(softwareProductId, action).then(() => {
+				fetchSoftwareProduct(softwareProductId).then(response => {
+					dispatch({
+						type: actionTypes.SOFTWARE_PRODUCT_LOADED,
+						response
+					});
+				});
+			});
+		}
+	},
+
+	switchVersion(dispatch, {softwareProductId, licenseModelId, version}) {
+		OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, version});
+	},
+
+	toggleNavigationItems(dispatch, {items, itemIdToExpand}) {
+		let mapOfExpandedIds = getExpandedItemsId(items, itemIdToExpand);
+		dispatch({
+			type: actionTypes.TOGGLE_NAVIGATION_ITEM,
+			mapOfExpandedIds
+		});
+	},
+
+	/** for the next verision */
+	addComponent(dispatch) {
+		return dispatch;
+	}
+};
+
+export default SoftwareProductActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js
new file mode 100644
index 0000000..812afe5
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+export default {
+
+	getCurrentCategoryOfSubCategory(selectedSubCategory, softwareProductCategories) {
+		let category, subCategory;
+		for (var i = 0; i < softwareProductCategories.length; i++) {
+			let {subcategories = []} = softwareProductCategories[i];
+			subCategory = subcategories.find(sub => sub.uniqueId === selectedSubCategory);
+			if (subCategory) {
+				category = softwareProductCategories[i].uniqueId;
+				break;
+			}
+		}
+		return category;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js
new file mode 100644
index 0000000..5f10c27
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	SOFTWARE_PRODUCT_LOADED: null,
+	SOFTWARE_PRODUCT_LIST_LOADED: null,
+	SOFTWARE_PRODUCT_LIST_EDIT: null,
+	SOFTWARE_PRODUCT_CATEGORIES_LOADED: null,
+	SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE: null,
+	ADD_SOFTWARE_PRODUCT: null,
+	TOGGLE_NAVIGATION_ITEM: null,
+
+	softwareProductEditor: {
+		OPEN: null,
+		CLOSE: null,
+		DATA_CHANGED: null,
+		IS_VALIDITY_DATA_CHANGED: null,
+		UPLOAD_CONFIRMATION: null
+	}
+});
+
+export const navigationItems = keyMirror({
+	VENDOR_SOFTWARE_PRODUCT: 'Vendor Software Product',
+	GENERAL: 'General',
+	PROCESS_DETAILS: 'Process Details',
+	NETWORKS: 'Networks',
+	ATTACHMENTS: 'Attachments',
+	COMPONENTS: 'Components',
+
+	COMPUTE: 'Compute',
+	LOAD_BALANCING: 'Load Balancing',
+	STORAGE: 'Storage',
+	MONITORING: 'Monitoring'
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js
new file mode 100644
index 0000000..6d1db16
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductConstants.js';
+
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.SOFTWARE_PRODUCT_LIST_LOADED:
+			return [...action.response.results];
+		case actionTypes.SOFTWARE_PRODUCT_LIST_EDIT:
+			const indexForEdit = state.findIndex(vsp => vsp.id === action.payload.softwareProduct.id);
+			return [...state.slice(0, indexForEdit), action.payload.softwareProduct, ...state.slice(indexForEdit + 1)];
+		case actionTypes.ADD_SOFTWARE_PRODUCT:
+			return [...state, action.softwareProduct];
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
new file mode 100644
index 0000000..784ac9d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {combineReducers} from 'redux';
+import {actionTypes} from './SoftwareProductConstants.js';
+import SoftwareProductAttachmentsReducer from './attachments/SoftwareProductAttachmentsReducer.js';
+import SoftwareProductCreationReducer from './creation/SoftwareProductCreationReducer.js';
+import SoftwareProductDetailsReducer from './details/SoftwareProductDetailsReducer.js';
+import SoftwareProductProcessesListReducer from './processes/SoftwareProductProcessesListReducer.js';
+import SoftwareProductProcessesEditorReducer from './processes/SoftwareProductProcessesEditorReducer.js';
+import SoftwareProductNetworksListReducer from './networks/SoftwareProductNetworksListReducer.js';
+import SoftwareProductComponentsListReducer from './components/SoftwareProductComponentsListReducer.js';
+import SoftwareProductComponentEditorReducer from './components/SoftwareProductComponentEditorReducer.js';
+import  {actionTypes as processesActionTypes} from './processes/SoftwareProductProcessesConstants.js';
+import SoftwareProductComponentProcessesListReducer  from './components/processes/SoftwareProductComponentProcessesListReducer.js';
+import SoftwareProductComponentProcessesEditorReducer from './components/processes/SoftwareProductComponentProcessesEditorReducer.js';
+import  {actionTypes as componentProcessesActionTypes} from './components/processes/SoftwareProductComponentProcessesConstants.js';
+import SoftwareProductComponentsNICListReducer from './components/network/SoftwareProductComponentsNICListReducer.js';
+import SoftwareProductComponentsNICEditorReducer from './components/network/SoftwareProductComponentsNICEditorReducer.js';
+import SoftwareProductComponentsMonitoringReducer from './components/monitoring/SoftwareProductComponentsMonitoringReducer.js';
+
+export default combineReducers({
+	softwareProductAttachments: SoftwareProductAttachmentsReducer,
+	softwareProductCreation: SoftwareProductCreationReducer,
+	softwareProductEditor: SoftwareProductDetailsReducer,
+	softwareProductProcesses: combineReducers({
+		processesList: SoftwareProductProcessesListReducer,
+		processesEditor: SoftwareProductProcessesEditorReducer,
+		processToDelete: (state = false, action) => action.type === processesActionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM ? action.processToDelete : state
+	}),
+	softwareProductNetworks: combineReducers({
+		networksList: SoftwareProductNetworksListReducer
+	}),
+	softwareProductComponents: combineReducers({
+		componentsList: SoftwareProductComponentsListReducer,
+		componentEditor: SoftwareProductComponentEditorReducer,
+		componentProcesses: combineReducers({
+			processesList: SoftwareProductComponentProcessesListReducer,
+			processesEditor: SoftwareProductComponentProcessesEditorReducer,
+			processToDelete: (state = false, action) => action.type === componentProcessesActionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM ? action.processToDelete : state,
+		}),
+		network: combineReducers({
+			nicList: SoftwareProductComponentsNICListReducer,
+			nicEditor: SoftwareProductComponentsNICEditorReducer
+		}),
+		monitoring: SoftwareProductComponentsMonitoringReducer
+	}),
+	softwareProductCategories: (state = [], action) => {
+		if (action.type === actionTypes.SOFTWARE_PRODUCT_CATEGORIES_LOADED) {
+			return action.softwareProductCategories;
+		}
+		return state;
+	},
+	softwareProductQuestionnaire: (state = {}, action) => {
+		if (action.type === actionTypes.SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE) {
+			return {
+				...state,
+				...action.payload
+			};
+		}
+		return state;
+	}
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js
new file mode 100644
index 0000000..a4b95a4
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductAttachmentsView from './SoftwareProductAttachmentsView.jsx';
+import SoftwareProductAttachmentsActionHelper from './SoftwareProductAttachmentsActionHelper.js';
+
+export const mapStateToProps = ({softwareProduct: {softwareProductAttachments}}) => {
+	let {attachmentsTree, hoveredNode, selectedNode, errorList} = softwareProductAttachments;
+	return {
+		attachmentsTree,
+		hoveredNode,
+		selectedNode,
+		errorList
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		toggleExpanded: (path) => SoftwareProductAttachmentsActionHelper.toggleExpanded(dispatch, {path}),
+		onSelectNode: (nodeName) => SoftwareProductAttachmentsActionHelper.onSelectNode(dispatch, {nodeName}),
+		onUnselectNode: () => SoftwareProductAttachmentsActionHelper.onUnselectNode(dispatch)
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductAttachmentsView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js
new file mode 100644
index 0000000..a7f7a51
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductAttachmentsConstants.js';
+
+export default {
+
+	toggleExpanded(dispatch, {path}) {
+		dispatch({
+			type: actionTypes.TOGGLE_EXPANDED,
+			path
+		});
+	},
+
+	onSelectNode(dispatch, {nodeName}) {
+		dispatch({
+			type: actionTypes.SELECTED_NODE,
+			nodeName
+		});
+	},
+
+	onUnselectNode(dispatch) {
+		dispatch({
+			type: actionTypes.UNSELECTED_NODE
+		});
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js
new file mode 100644
index 0000000..33af476
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+export const actionTypes = keyMirror({
+	TOGGLE_EXPANDED: null,
+	SELECTED_NODE: null,
+	UNSELECTED_NODE: null
+});
+
+export const errorTypes = keyMirror({
+	MISSING_FILE_IN_ZIP: i18n('missing file in zip'),
+	MISSING_FILE_IN_MANIFEST: i18n('missing file in manifest'),
+	MISSING_OR_ILLEGAL_FILE_TYPE_IN_MANIFEST: i18n('missing or illegal file type in manifest'),
+	FILE_IS_YML_WITHOUT_YML_EXTENSION: i18n('file is defined as a heat file but it doesn\'t have .yml or .yaml extension'),
+	FILE_IS_ENV_WITHOUT_ENV_EXTENSION: i18n('file is defined as an env file but it doesn\'t have .env extension'),
+	ILLEGAL_YAML_FILE_CONTENT: i18n('illegal yaml file content'),
+	ILLEGAL_HEAT_YAML_FILE_CONTENT: i18n('illegal HEAT yaml file content'),
+	MISSING_FILE_NAME_IN_MANIFEST: i18n('a file is written in manifest without file name'),
+	MISSING_ENV_FILE_IN_ZIP: i18n('missing env file in zip'),
+	ARTIFACT_NOT_IN_USE: i18n('artifact not in use')
+});
+
+export const nodeTypes = keyMirror({
+	heat: i18n('Heat'),
+	volume: i18n('Volume'),
+	network: i18n('Network'),
+	artifact: i18n('Artifact'),
+	env: i18n('Environment'),
+	other: i18n('')
+});
+
+export const mouseActions = keyMirror({
+	MOUSE_BUTTON_CLICK: 0
+});
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js
new file mode 100644
index 0000000..5c5567b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js
@@ -0,0 +1,199 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes as softwareProductsActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+import {actionTypes} from './SoftwareProductAttachmentsConstants.js';
+
+const mapVolumeData = ({fileName, env, errors}) => ({
+	name: fileName,
+	expanded: true,
+	type: 'volume',
+	children: env && [{
+		name: env.fileName,
+		errors: env.errors,
+		type: 'env'
+	}],
+	errors
+});
+
+const mapNetworkData = ({fileName, env, errors}) => ({
+	name: fileName,
+	expanded: true,
+	type: 'network',
+	children: env && [{
+		name: env.fileName,
+		errors: env.errors,
+		type: 'env'
+	}],
+	errors
+});
+
+const mapArtifactsData = ({fileName, errors}) => ({
+	name: fileName,
+	type: 'artifact',
+	errors
+});
+
+const mapOtherData = ({fileName, errors}) => ({
+	name: fileName,
+	type: 'other',
+	errors
+});
+
+
+const mapHeatData = ({fileName, env, nested, volume, network, artifacts, errors, other}) => ({
+	name: fileName,
+	expanded: true,
+	type: 'heat',
+	errors,
+	children: [
+		...(volume ? volume.map(mapVolumeData) : []),
+		...(network ? network.map(mapNetworkData) : []),
+		...(env ? [{
+			name: env.fileName,
+			errors: env.errors,
+			type: 'env'
+		}] : []),
+		...(artifacts ? artifacts.map(mapArtifactsData) : []),
+		...(other ? other.map(mapOtherData) : []),
+		...(nested ? nested.map(mapHeatData) : [])
+	]
+});
+
+function createErrorList(node, parent, deep = 0, errorList = []) {
+	if (node.errors) {
+		errorList.push(...node.errors.map((error) => ({
+			errorLevel: error.level,
+			errorMessage: error.message,
+			name: node.name,
+			hasParent: deep > 2,
+			parentName: parent.name,
+			type: node.type,
+		})));
+	}
+	if (node.children && node.children.length) {
+		node.children.map((child) => createErrorList(child, node, deep + 1, errorList));
+	}
+	return errorList;
+}
+
+const mapValidationDataToTree = validationData => {
+	let {HEAT, volume, network, artifacts, other} = validationData.importStructure || {};
+	return {
+		children: [
+			{
+				name: 'HEAT',
+				expanded: true,
+				type: 'heat',
+				children: (HEAT ? HEAT.map(mapHeatData) : [])
+			},
+			...(artifacts ? [{
+				name: 'artifacts',
+				expanded: true,
+				type: 'artifact',
+				children: (artifacts ? artifacts.map(mapArtifactsData) : [])
+			}] : []),
+			...(network ? [{
+				name: 'networks',
+				expanded: true,
+				type: 'network',
+				children: (network ? network.map(mapNetworkData) : []),
+			}] : []),
+			...(volume ? [{
+				name: 'volume',
+				expanded: true,
+				type: 'volume',
+				children: (volume ? volume.map(mapVolumeData) : []),
+			}] : []),
+			...(other ? [{
+				name: 'other',
+				expanded: true,
+				type: 'other',
+				children: (other ? other.map(mapOtherData) : []),
+			}] : [])
+		]
+	};
+};
+
+const toggleExpanded = (node, path) => {
+	let newNode = {...node};
+	if (path.length === 0) {
+		newNode.expanded = !node.expanded;
+	} else {
+		let index = path[0];
+		newNode.children = [
+			...node.children.slice(0, index),
+			toggleExpanded(node.children[index], path.slice(1)),
+			...node.children.slice(index + 1)
+		];
+	}
+	return newNode;
+};
+
+const expandSelected = (node, selectedNode) => {
+	let shouldExpand = node.name === selectedNode;
+	let children = node.children && node.children.map(child => {
+		let {shouldExpand: shouldExpandChild, node: newChild} = expandSelected(child, selectedNode);
+		shouldExpand = shouldExpand || shouldExpandChild;
+		return newChild;
+	});
+
+	return {
+		node: {
+			...node,
+			expanded: node.expanded || shouldExpand,
+			children
+		},
+		shouldExpand
+	};
+};
+
+export default (state = {attachmentsTree: {}}, action) => {
+	switch (action.type) {
+		case softwareProductsActionTypes.SOFTWARE_PRODUCT_LOADED:
+			let currentSoftwareProduct = action.response;
+			let attachmentsTree = currentSoftwareProduct.validationData ? mapValidationDataToTree(currentSoftwareProduct.validationData) : {};
+			let errorList = createErrorList(attachmentsTree);
+			return {
+				...state,
+				attachmentsTree,
+				errorList
+			};
+		case actionTypes.TOGGLE_EXPANDED:
+			return {
+				...state,
+				attachmentsTree: toggleExpanded(state.attachmentsTree, action.path)
+			};
+		case actionTypes.SELECTED_NODE:
+			let selectedNode = action.nodeName;
+			return {
+				...state,
+				attachmentsTree: expandSelected(state.attachmentsTree, selectedNode).node,
+				selectedNode
+			};
+		case actionTypes.UNSELECTED_NODE:
+			return {
+				...state,
+				selectedNode: undefined
+			};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx
new file mode 100644
index 0000000..c52999c
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx
@@ -0,0 +1,182 @@
+import React from 'react';
+import FontAwesome from 'react-fontawesome';
+import classNames from 'classnames';
+import Collapse from 'react-bootstrap/lib/Collapse.js';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {nodeTypes, mouseActions} from './SoftwareProductAttachmentsConstants';
+
+const typeToIcon = Object.freeze({
+	heat: 'building-o',
+	volume: 'database',
+	network: 'cloud',
+	artifact: 'gear',
+	env: 'server',
+	other: 'cube'
+});
+
+const leftPanelWidth = 250;
+
+class SoftwareProductAttachmentsView extends React.Component {
+
+	static propTypes = {
+		attachmentsTree: React.PropTypes.object.isRequired
+	};
+	state = {
+		treeWidth: '400'
+	};
+
+	render() {
+		let {attachmentsTree, errorList} = this.props;
+		let {treeWidth} = this.state;
+		return (
+			<div className='software-product-attachments'>
+				<div className='software-product-attachments-tree' style={{'width' : treeWidth + 'px'}}>
+					<div className='tree-wrapper'>
+						{
+							attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind]))
+						}
+					</div>
+				</div>
+				<div onMouseDown={(e) => this.onChangeTreeWidth(e)} className='software-product-attachments-separator'/>
+
+				<div className='software-product-attachments-error-list'>
+					{errorList.length ? this.renderErrorList(errorList) : <div className='no-errors'>{attachmentsTree.children ?
+						i18n('VALIDATION SUCCESS') : i18n('THERE IS NO HEAT DATA TO PRESENT') }</div>}
+				</div>
+			</div>
+		);
+	}
+
+	renderNode(node, path) {
+		let isFolder = node.children && node.children.length > 0;
+		let {onSelectNode} = this.props;
+		return (
+			<div key={node.name} className='tree-block-inside'>
+				{
+					<div onDoubleClick={() => this.props.toggleExpanded(path)} className={this.getTreeRowClassName(node.name)}>
+						{
+							isFolder &&
+							<div onClick={() => this.props.toggleExpanded(path)} className={classNames('tree-node-expander', {'tree-node-expander-collapsed': !node.expanded})}>
+								<FontAwesome name='caret-down'/>
+							</div>
+						}
+						{
+
+							<span className='tree-node-icon'>
+								<FontAwesome name={typeToIcon[node.type]}/>
+							</span>
+						}
+						{
+
+							<span onClick={() => onSelectNode(node.name)} className={this.getTreeTextClassName(node)}>
+							{node.name}
+							</span>
+						}
+					</div>
+				}
+				{
+					isFolder &&
+					<Collapse in={node.expanded}>
+						<div className='tree-node-children'>
+							{
+								node.children.map((child, ind) => this.renderNode(child, [...path, ind]))
+							}
+						</div>
+					</Collapse>
+				}
+			</div>
+		);
+	}
+
+	createErrorList(errorList, node, parent) {
+		if (node.errors) {
+			node.errors.forEach(error => errorList.push({
+				error,
+				name: node.name,
+				parentName: parent.name,
+				type: node.type
+			}));
+		}
+		if (node.children && node.children.length) {
+			node.children.map((child) => this.createErrorList(errorList, child, node));
+		}
+	}
+
+	renderErrorList(errors) {
+		let prevError = {};
+		let {selectedNode} = this.props;
+		return errors.map(error => {
+			let isSameNodeError = error.name === prevError.name && error.parentName === prevError.parentName;
+			prevError = error;
+
+			return (
+				<div
+					key={error.name + error.errorMessage + error.parentName}
+
+					onClick={() => this.selectNode(error.name)}
+					className={classNames('error-item', {'clicked': selectedNode === error.name, 'shifted': !isSameNodeError})}>
+					<span className={classNames('error-item-file-type', {'strong': !isSameNodeError})}>
+					{
+						error.hasParent ?
+							i18n('{type}  {name} in {parentName}: ', {
+								type: nodeTypes[error.type],
+								name: error.name,
+								parentName: error.parentName
+							}) :
+							i18n('{type}  {name}: ', {
+								type: nodeTypes[error.type],
+								name: error.name
+							})
+					}
+					</span>
+					<span className={`error-item-file-type ${error.errorLevel}`}> {error.errorMessage} </span>
+				</div>
+			);
+		});
+	}
+
+	selectNode(currentSelectedNode) {
+		let {onUnselectNode, onSelectNode, selectedNode} = this.props;
+		if (currentSelectedNode !== selectedNode) {
+			onSelectNode(currentSelectedNode);
+		}else{
+			onUnselectNode();
+		}
+
+	}
+
+	getTreeRowClassName(name) {
+		let {hoveredNode, selectedNode} = this.props;
+		return classNames({
+			'tree-node-row': true,
+			'tree-node-selected': name === hoveredNode,
+			'tree-node-clicked': name === selectedNode
+		});
+	}
+
+	getTreeTextClassName(node) {
+		let {selectedNode} = this.props;
+		return classNames({
+			'tree-element-text': true,
+			'error-status': node.errors,
+			'error-status-selected': node.name === selectedNode
+		});
+	}
+
+	onChangeTreeWidth(e) {
+		if (e.button === mouseActions.MOUSE_BUTTON_CLICK) {
+			let onMouseMove = (e) => {
+				this.setState({treeWidth: e.clientX - leftPanelWidth});
+			};
+			let onMouseUp = () => {
+				document.removeEventListener('mousemove', onMouseMove);
+				document.removeEventListener('mouseup', onMouseUp);
+			};
+			document.addEventListener('mousemove', onMouseMove);
+			document.addEventListener('mouseup', onMouseUp);
+		}
+	}
+}
+
+export default SoftwareProductAttachmentsView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js
new file mode 100644
index 0000000..3b8bc4f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentsConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.COMPONENT_UPDATE:
+			return {
+				...state,
+				data: action.component
+			};
+		case actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE:
+			return {
+				...state,
+				qdata: action.payload.qdata || state.qdata,
+				qschema: action.payload.qschema || state.qschema
+			};
+		case actionTypes.COMPONENT_DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js
new file mode 100644
index 0000000..e53b2ec
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js
@@ -0,0 +1,129 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+
+import {actionTypes} from './SoftwareProductComponentsConstants.js';
+
+function baseUrl(softwareProductId) {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components`;
+}
+
+function fetchSoftwareProductComponents(softwareProductId, version) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}${versionQuery}`);
+}
+
+function putSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, vspComponent) {
+	return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${vspComponentId}/questionnaire`, vspComponent);
+}
+
+function fetchSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, version){
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}/${vspComponentId}/questionnaire${versionQuery}`);
+}
+
+function fetchSoftwareProductComponent(softwareProductId, vspComponentId, version){
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}/${vspComponentId}${versionQuery}`);
+}
+
+function putSoftwareProductComponent(softwareProductId, vspComponentId, vspComponent) {
+	return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${vspComponentId}`, {
+		name: vspComponent.name,
+		displayName: vspComponent.displayName,
+		description: vspComponent.description
+	});
+}
+
+const SoftwareProductComponentsActionHelper = {
+	fetchSoftwareProductComponents(dispatch, {softwareProductId, version}) {
+		return fetchSoftwareProductComponents(softwareProductId, version).then(response => {
+			dispatch({
+				type: actionTypes.COMPONENTS_LIST_UPDATE,
+				componentsList: response.results
+			});
+		});
+	},
+
+	componentDataChanged(dispatch, {deltaData}) {
+		dispatch({
+			type: actionTypes.COMPONENT_DATA_CHANGED,
+			deltaData
+		});
+	},
+
+
+	updateSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId, componentData, qdata}) {
+		return Promise.all([
+			SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, qdata}),
+			SoftwareProductComponentsActionHelper.updateSoftwareProductComponentData(dispatch, {softwareProductId, vspComponentId, componentData})
+		]);
+	},
+
+	updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, qdata}) {
+		return putSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, qdata);
+	},
+
+	updateSoftwareProductComponentData(dispatch, {softwareProductId, vspComponentId, componentData}) {
+		return putSoftwareProductComponent(softwareProductId, vspComponentId, componentData).then(() => dispatch({
+			type: actionTypes.COMPONENTS_LIST_EDIT,
+			component: {
+				id: vspComponentId,
+				...componentData
+			}
+		}));
+	},
+
+
+	fetchSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, version}) {
+		return fetchSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, version).then(response => {
+			dispatch({
+				type: actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE,
+				payload: {
+					qdata: response.data ? JSON.parse(response.data) : {},
+					qschema: JSON.parse(response.schema)
+				}
+			});
+		});
+	},
+
+	fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId, version}) {
+		return fetchSoftwareProductComponent(softwareProductId, vspComponentId, version).then(response => {
+			dispatch({
+				type: actionTypes.COMPONENT_UPDATE,
+				component: response.data
+			});
+		});
+	},
+
+	componentQuestionnaireUpdated(dispatch, {data}) {
+		dispatch({
+			type: actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE,
+			payload: {
+				qdata: data
+			}
+		});
+	},
+};
+
+export default SoftwareProductComponentsActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js
new file mode 100644
index 0000000..dee517e
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	COMPONENTS_LIST_UPDATE: null,
+	COMPONENTS_LIST_EDIT: null,
+	COMPONENT_UPDATE: null,
+	COMPONENT_DATA_CHANGED: null,
+	COMPONENT_QUESTIONNAIRE_UPDATE: null
+});
+
+export const storageConstants  = keyMirror({
+	backupType: {
+		ON_SITE: 'OnSite',
+		OFF_SITE: 'OffSite'
+	}
+});
+
+export const navigationItems = keyMirror({
+	STORAGE: 'Storage',
+	PROCESS_DETAILS: 'Process Details',
+	MONITORING: 'Monitoring',
+	NETWORK: 'Network',
+	COMPUTE: 'Compute',
+	NETWORK: 'Network',
+	LOAD_BALANCING: 'High Availability & Load Balancing'
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js
new file mode 100644
index 0000000..f1c1ed1
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentsListView from './SoftwareProductComponentsListView.jsx';
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+
+const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductEditor: {data: currentSoftwareProduct}, softwareProductComponents} = softwareProduct;
+	let {componentsList} = softwareProductComponents;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+
+	return {
+		currentSoftwareProduct,
+		isReadOnlyMode,
+		componentsList
+	};
+};
+
+
+const mapActionToProps = (dispatch, {version}) => {
+	return {
+		onComponentSelect: ({id: softwareProductId, componentId}) => {
+			OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version });
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionToProps, null, {withRef: true})(SoftwareProductComponentsListView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js
new file mode 100644
index 0000000..b91362a
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentsConstants.js';
+
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.COMPONENTS_LIST_UPDATE:
+			return [...action.componentsList];
+		case actionTypes.COMPONENTS_LIST_EDIT:
+			const indexForEdit = state.findIndex(component => component.id === action.component.id);
+			return [...state.slice(0, indexForEdit), action.component, ...state.slice(indexForEdit + 1)];
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx
new file mode 100644
index 0000000..0c0ba0f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx
@@ -0,0 +1,89 @@
+import React from 'react';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+
+const ComponentPropType = React.PropTypes.shape({
+	id: React.PropTypes.string,
+	name: React.PropTypes.string,
+	displayName: React.PropTypes.string,
+	description: React.PropTypes.string
+});
+
+class SoftwareProductComponentsListView extends React.Component {
+
+	state = {
+		localFilter: ''
+	};
+
+	static propTypes = {
+		isReadOnlyMode: React.PropTypes.bool,
+		componentsList: React.PropTypes.arrayOf(ComponentPropType),
+		onComponentSelect: React.PropTypes.func
+	};
+
+	render() {
+		let {componentsList = []} =  this.props;
+		return (
+			<div className=''>
+				{
+					componentsList.length > 0 && this.renderComponents()
+				}
+			</div>
+		);
+	}
+
+	renderComponents() {
+		const {localFilter} = this.state;
+		let {isReadOnlyMode} =  this.props;
+
+		return (
+			<ListEditorView
+				title={i18n('Virtual Function Components')}
+				filterValue={localFilter}
+				placeholder={i18n('Filter Components')}
+				onFilter={filter => this.setState({localFilter: filter})}
+				isReadOnlyMode={isReadOnlyMode}>
+				{this.filterList().map(component => this.renderComponentsListItem(component))}
+			</ListEditorView>
+		);
+	}
+
+	renderComponentsListItem(component) {
+		let {id: componentId, name, displayName, description = ''} = component;
+		let {currentSoftwareProduct: {id}, onComponentSelect} = this.props;
+		return (
+			<ListEditorItemView
+				key={name + Math.floor(Math.random() * (100 - 1) + 1).toString()}
+				className='list-editor-item-view'
+				onSelect={() => onComponentSelect({id, componentId})}>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Component')}</div>
+					<div className='name'>{displayName}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Description')}</div>
+					<div className='description'>{description}</div>
+				</div>
+			</ListEditorItemView>
+		);
+	}
+
+	filterList() {
+		let {componentsList = []} = this.props;
+
+		let {localFilter} = this.state;
+		if (localFilter.trim()) {
+			const filter = new RegExp(escape(localFilter), 'i');
+			return componentsList.filter(({displayName = '', description = ''}) => {
+				return escape(displayName).match(filter) || escape(description).match(filter);
+			});
+		}
+		else {
+			return componentsList;
+		}
+	}
+}
+
+export default SoftwareProductComponentsListView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js
new file mode 100644
index 0000000..7ac1c70
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentComputeView from './SoftwareProductComponentComputeView.jsx';
+import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+
+const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
+	let {componentEditor: {qdata, qschema}} = softwareProductComponents;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+
+	let minNumberOfVMsSelectedByUser = 0;
+	if(qdata && qdata.compute && qdata.compute.numOfVMs){
+		minNumberOfVMsSelectedByUser = qdata.compute.numOfVMs.minimum || 0;
+	}
+
+	return {
+		qdata,
+		qschema,
+		isReadOnlyMode,
+		minNumberOfVMsSelectedByUser
+	};
+};
+
+const mapActionToProps = (dispatch, {softwareProductId, componentId}) => {
+	return {
+		onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+		onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});}
+	};
+};
+
+export default connect(mapStateToProps, mapActionToProps, null, {withRef: true}) (SoftwareProductComponentComputeView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx
new file mode 100644
index 0000000..3bad147
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx
@@ -0,0 +1,129 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+
+
+class SoftwareProductComponentComputeView extends React.Component {
+
+	static propTypes = {
+		qdata: React.PropTypes.object,
+		qschema: React.PropTypes.object,
+		isReadOnlyMode: React.PropTypes.bool,
+		minNumberOfVMsSelectedByUser: React.PropTypes.number,
+		onQDataChanged: React.PropTypes.func.isRequired,
+		onSubmit: React.PropTypes.func.isRequired
+	};
+
+	render() {
+		let {qdata, qschema, isReadOnlyMode, minNumberOfVMsSelectedByUser, onQDataChanged, onSubmit} = this.props;
+
+		return (
+			<div className='vsp-component-questionnaire-view'>
+				<ValidationForm
+					ref='computeValidationForm'
+					hasButtons={false}
+					onSubmit={() => onSubmit({qdata})}
+					className='component-questionnaire-validation-form'
+					isReadOnlyMode={isReadOnlyMode}
+					onDataChanged={onQDataChanged}
+					data={qdata}
+					schema={qschema}>
+
+					<div className='section-title'>{i18n('VM Sizing')}</div>
+					<div className='rows-section'>
+						<div className='row-flex-components input-row'>
+							<div className='single-col'>
+								<ValidationInput
+									type='text'
+									label={i18n('Number of CPUs')}
+									pointer={'/compute/vmSizing/numOfCPUs'}/>
+							</div>
+							<div className='single-col'>
+								<ValidationInput
+									type='text'
+									label={i18n('File System Size (GB)')}
+									pointer={'/compute/vmSizing/fileSystemSizeGB'}/>
+							</div>
+							<div className='single-col'>
+								<ValidationInput
+									type='text'
+									label={i18n('Persistent Storage/Volume Size (GB)')}
+									pointer={'/compute/vmSizing/persistentStorageVolumeSize'}/>
+							</div>
+							<ValidationInput
+								type='text'
+								label={i18n('I/O Operations (per second)')}
+								pointer={'/compute/vmSizing/IOOperationsPerSec'}/>
+						</div>
+					</div>
+					<div className='section-title'>{i18n('Number of VMs')}</div>
+					<div className='rows-section'>
+						<div className='row-flex-components input-row'>
+							<div className='single-col'>
+								<ValidationInput
+									type='text'
+									label={i18n('Minimum')}
+									pointer={'/compute/numOfVMs/minimum'}/>
+							</div>
+							<div className='single-col'>
+								<ValidationInput
+									type='text'
+									label={i18n('Maximum')}
+									pointer={'/compute/numOfVMs/maximum'}
+									validations={{minValue: minNumberOfVMsSelectedByUser}}/>
+							</div>
+							<div className='single-col'>
+								<ValidationInput
+									type='select'
+									label={i18n('CPU Oversubscription Ratio')}
+									pointer={'/compute/numOfVMs/CpuOverSubscriptionRatio'}/>
+							</div>
+							<ValidationInput
+								type='select'
+								label={i18n('Memory - RAM')}
+								pointer={'/compute/numOfVMs/MemoryRAM'}/>
+						</div>
+					</div>
+
+					<div className='section-title'>{i18n('Guest OS')}</div>
+					<div className='rows-section'>
+						<div className='section-field row-flex-components input-row'>
+							<div className='two-col'>
+								<ValidationInput
+									label={i18n('Guest OS')}
+									type='text'
+									pointer={'/compute/guestOS/name'}/>
+							</div>
+							<div className='empty-two-col'/>
+						</div>
+						<div className='vertical-flex input-row'>
+							<label key='label' className='control-label'>{i18n('OS Bit Size')}</label>
+							<div className='radio-options-content-row input-row'>
+								<ValidationInput
+									type='radiogroup'
+									pointer={'/compute/guestOS/bitSize'}
+									className='radio-field'/>
+							</div>
+						</div>
+						<div className='section-field row-flex-components input-row'>
+							<div className='two-col'>
+								<ValidationInput
+									type='textarea'
+									label={i18n('Guest OS Tools:')}
+									pointer={'/compute/guestOS/tools'}/>
+							</div>
+							<div className='empty-two-col'/>
+						</div>
+					</div>
+				</ValidationForm>
+			</div>
+		);
+	}
+
+	save(){
+		return this.refs.computeValidationForm.handleFormSubmit(new Event('dummy'));
+	}
+}
+
+export default SoftwareProductComponentComputeView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js
new file mode 100644
index 0000000..e4c330b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentsGeneralView from './SoftwareProductComponentsGeneralView.jsx';
+import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+export const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
+	let {componentEditor: {data: componentData = {} , qdata, qschema}} = softwareProductComponents;
+
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+
+	return {
+		componentData,
+		qdata,
+		qschema,
+		isReadOnlyMode
+	};
+};
+
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+	return {
+		onDataChanged: deltaData => SoftwareProductComponentsActionHelper.componentDataChanged(dispatch, {deltaData}),
+		onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+		onSubmit: ({componentData, qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch,
+			{softwareProductId, vspComponentId: componentId, componentData, qdata});
+		}
+	};
+
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsGeneralView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx
new file mode 100644
index 0000000..5d11e42
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx
@@ -0,0 +1,186 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+
+
+class SoftwareProductComponentsGeneralView extends React.Component {
+
+	render() {
+		let {qdata, qschema, onQDataChanged, onDataChanged, componentData: {displayName, description}, isReadOnlyMode} =  this.props;
+		return(
+			<div className='vsp-components-general'>
+				<div className='general-data'>
+					<ValidationForm
+						isReadOnlyMode={isReadOnlyMode}
+						hasButtons={false}>
+					<div className=''>
+						<h3 className='section-title'>{i18n('General')}</h3>
+						<div className='rows-section'>
+							<div className='row-flex-components input-row'>
+							{/** disabled until backend will be ready to implement it
+							 <div className='validation-input-wrapper'>
+							 <div className='form-group'>
+							 <label className='control-label'>{i18n('Name')}</label>
+							 <div>{name}</div>
+							 </div>
+							 </div>
+
+							*/}
+								<div className='single-col'>
+									<ValidationInput label={i18n('Name')} value={displayName}	disabled={true}	type='text'/>
+								</div>
+								<div className='two-col'>
+								<ValidationInput
+									label={i18n('Description')}
+									onChange={description => onDataChanged({description})}
+									disabled={isReadOnlyMode}
+									value={description}
+									type='textarea'/>
+								</div>
+								<div className='empty-col' />
+							</div>
+						</div>
+					</div>
+						</ValidationForm>
+					{
+						qschema &&
+					<ValidationForm
+						onDataChanged={onQDataChanged}
+						data={qdata}
+						schema={qschema}
+						isReadOnlyMode={isReadOnlyMode}
+						hasButtons={false}>
+							<h3 className='section-title additional-validation-form'>{i18n('Hypervisor')}</h3>
+							<div className='rows-section'>
+								<div className='row-flex-components input-row'>
+									<div className='single-col'>
+										<ValidationInput
+											label={i18n('Supported Hypervisors')}
+											type='select'
+											pointer='/general/hypervisor/hypervisor'/>
+										</div>
+									<div className='two-col'>
+										<ValidationInput
+											label={i18n('Hypervisor Drivers')}
+											type='text'
+											pointer='/general/hypervisor/drivers'/>
+									</div>
+									<div className='empty-col' />
+								</div>
+								<div className='row-flex-components input-row'>
+									<div className='three-col'>
+										<ValidationInput
+											label={i18n('Describe Container Features')}
+											type='textarea'
+											pointer='/general/hypervisor/containerFeaturesDescription'/>
+									</div>
+									<div className='empty-col' />
+								</div>
+							</div>
+							<h3 className='section-title'>{i18n('Image')}</h3>
+							<div className='rows-section'>
+								<div className='row-flex-components input-row'>
+									<div className='single-col'>
+										<ValidationInput
+											label={i18n('Image format')}
+											type='select'
+											pointer='/general/image/format'/>
+									</div>
+									<div className='single-col'>
+										<ValidationInput
+											label={i18n('Image provided by')}
+											type='select'
+											pointer='/general/image/providedBy'/>
+									</div>
+									<div className='single-col'>
+										<ValidationInput
+											label={i18n('Size of boot disk per VM (GB)')}
+											type='text'
+											pointer='/general/image/bootDiskSizePerVM'/>
+									</div>
+									<ValidationInput
+										label={i18n('Size of ephemeral disk per VM (GB)')}
+										type='text'
+										pointer='/general/image/ephemeralDiskSizePerVM'/>
+								</div>
+							</div>
+							<h3 className='section-title'>{i18n('Recovery')}</h3>
+							<div className='rows-section'>
+								<div className='row-flex-components input-row'>
+									<div className='single-col'>
+										<ValidationInput
+											label={i18n('VM Recovery Point Objective (Minutes)')}
+											type='text'
+											pointer='/general/recovery/pointObjective'/>
+									</div>
+									<ValidationInput
+										label={i18n('VM Recovery Time Objective (Minutes)')}
+										type='text'
+										pointer='/general/recovery/timeObjective'/>
+									<div className='empty-two-col' />
+								</div>
+
+
+								<div className='row-flex-components input-row'>
+									<div className='two-col'>
+										<ValidationInput
+											className='textarea'
+											label={i18n('How are in VM process failures handled?')}
+											type='textarea'
+											pointer='/general/recovery/vmProcessFailuresHandling'/>
+									</div>
+									<div className='empty-two-col' />
+									{
+										/** disabled until backend will be ready to implement it
+											<div className='row'>
+												<div className='col-md-3'>
+													<ValidationInput
+														label={i18n('VM Recovery Document')}
+														type='text'
+														pointer='/general/recovery/VMRecoveryDocument'/>
+												</div>
+											</div>
+										 */
+									}
+									</div>
+								</div>
+								<h3 className='section-title'>{i18n('DNS Configuration')}</h3>
+								<div className='rows-section'>
+									<div className='row-flex-components input-row'>
+										<div className='two-col'>
+											<ValidationInput
+												label={i18n('Do you have a need for DNS as a Service? Please describe.')}
+												type='textarea'
+												pointer='/general/dnsConfiguration'/>
+										</div>
+										<div className='empty-two-col' />
+									</div>
+								</div>
+								<h3 className='section-title'>{i18n('Clone')}</h3>
+								<div className='rows-section'>
+									<div className='row-flex-components input-row'>
+										<div className='two-col'>
+											<ValidationInput
+												label={i18n('Describe VM Clone Use')}
+												type='textarea'
+												pointer='/general/vmCloneUsage'/>
+										</div>
+										<div className='empty-two-col' />
+									</div>
+								</div>
+					</ValidationForm>
+					}
+				</div>
+			</div>
+		);
+	}
+
+	save() {
+		let {onSubmit, componentData, qdata} = this.props;
+		return onSubmit({componentData, qdata});
+	}
+}
+
+export default SoftwareProductComponentsGeneralView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js
new file mode 100644
index 0000000..4d4034d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentLoadBalancingView from './SoftwareProductComponentLoadBalancingRefView.jsx';
+import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+export const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
+	let {componentEditor: {qdata, qschema}} = softwareProductComponents;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+
+	return {
+		qdata,
+		qschema,
+		isReadOnlyMode
+	};
+};
+
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+	return {
+		onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+		onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});}
+	};
+
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentLoadBalancingView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx
new file mode 100644
index 0000000..1aa2bab
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx
@@ -0,0 +1,103 @@
+import React from 'react';
+import FontAwesome from 'react-fontawesome';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+
+const prefix = '/highAvailabilityAndLoadBalancing/';
+
+const pointers = [
+	{
+		key: 'failureLoadDistribution',
+		description: 'How is load distributed across live vms in the event of a vm/host failure? please describe'
+	},
+	{
+		key: 'nkModelImplementation',
+		description: 'Does each VM implement the N+K model for redundancy and failure protection? Please describe.'
+	},
+	{
+		key: 'architectureChoice',
+		description: 'What architecture is being implemented: ACTIVE-ACTIVE and/or ACTIVE-PASSIVE. ',
+		added: 'Will the arrangement be 1-1 or N-M? Please describe.'
+	},
+	{key: 'slaRequirements', description: 'Specify application SLA requirements on Cloud platform.'},
+	{
+		key: 'horizontalScaling',
+		description: 'Is horizontal scaling the preferred solution for HA and resiliency? Please describe.'
+	},
+	{
+		key: 'loadDistributionMechanism',
+		description: 'Can load be distributed across VMs? If so, are special mechanisms needed to re-balance data across VMs?',
+		added: 'Please describe.'
+	}
+];
+
+class SoftwareProductComponentLoadBalancingView extends React.Component {
+	static propTypes = {
+		componentId: React.PropTypes.string.isRequired,
+		softwareProductId: React.PropTypes.string.isRequired,
+		qdata: React.PropTypes.object,
+		qschema: React.PropTypes.object,
+		currentSoftwareProduct: React.PropTypes.object
+	};
+
+	state = {
+		expanded: {}
+	};
+
+	renderTextAreaItem(item) {
+		return (
+			<div className='question'>
+				<div className={this.state.expanded[item.key] ? 'title' : 'title add-padding'}
+					 onClick={() => this.toggle(item.key)}>
+					<FontAwesome name={this.state.expanded[item.key] ? 'chevron-up' : 'chevron-down'}/>
+					{i18n(item.description)}
+					{item.added && <div className='new-line'>{i18n(item.added)}</div>}
+				</div>
+				<div className={this.state.expanded[item.key] ? 'collapse in' : 'collapse'}>
+					<div className='row'>
+						<div className='col-md-9'>
+							<ValidationInput
+								type='textarea'
+								pointer={`${prefix}${item.key}`}
+								maxLength='1000' />
+						</div>
+					</div>
+				</div>
+			</div>
+		);
+	}
+
+	render() {
+		let {qdata, qschema, onQDataChanged, isReadOnlyMode} = this.props;
+		return (
+			<div className='vsp-components-load-balancing'>
+				<div className='halb-data'>
+					<div className='load-balancing-page-title'>{i18n('High Availability & Load Balancing')}</div>
+					<ValidationForm
+						onDataChanged={onQDataChanged}
+						data={qdata} schema={qschema}
+						isReadOnlyMode={isReadOnlyMode}
+						hasButtons={false}>
+						{pointers.map(pointer => this.renderTextAreaItem(pointer))}
+					</ValidationForm>
+				</div>
+			</div>
+		);
+	}
+
+	toggle(name) {
+		let st = this.state.expanded[name] ? true : false;
+		let newState = {...this.state};
+		newState.expanded[name] = !st;
+		this.setState(newState);
+	}
+
+	save() {
+		let {onSubmit, qdata} = this.props;
+		return onSubmit({qdata});
+	}
+}
+
+export default SoftwareProductComponentLoadBalancingView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js
new file mode 100644
index 0000000..ed7c5a1
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import SoftwareProductComponentsMonitoringView from './SoftwareProductComponentsMonitoringView.jsx';
+import SoftwareProductComponentsMonitoringAction from './SoftwareProductComponentsMonitoringActionHelper.js';
+
+
+export const mapStateToProps = ({softwareProduct}) => {
+
+	let {softwareProductEditor: {data:currentVSP = {}}, softwareProductComponents: {monitoring}} = softwareProduct;
+	let {trapFilename, pollFilename} = monitoring;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+
+	return {
+		isReadOnlyMode,
+		trapFilename,
+		pollFilename
+	};
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+	return {
+		onDropMibFileToUpload: (formData, type) =>
+			SoftwareProductComponentsMonitoringAction.uploadSnmpFile(dispatch, {
+				softwareProductId,
+				componentId,
+				formData,
+				type
+			}),
+
+		onDeleteSnmpFile: type => SoftwareProductComponentsMonitoringAction.deleteSnmpFile(dispatch, {
+			softwareProductId,
+			componentId,
+			type
+		})
+
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsMonitoringView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js
new file mode 100644
index 0000000..3faf571
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import SoftwareProductComponentsMonitoringConstants, {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js';
+
+const UPLOAD = true;
+
+function baseUrl(vspId, componentId) {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-software-products/${vspId}/components/${componentId}/monitors`;
+}
+
+function snmpTrapUrl(vspId, componentId, isUpload) {
+	return `${baseUrl(vspId, componentId)}/snmp-trap${isUpload ? '/upload' : ''}`;
+}
+
+function snmpPollUrl(vspId, componentId, isUpload) {
+	return `${baseUrl(vspId, componentId)}/snmp${isUpload ? '/upload' : ''}`;
+}
+
+let onInvalidFileSizeUpload = (dispatch) => dispatch({
+	type: NotificationConstants.NOTIFY_ERROR,
+	data: {
+		title: i18n('Upload Failed'),
+		msg: i18n('no zip file was uploaded or zip file doesn\'t exist')
+	}
+});
+
+let uploadSnmpTrapFile = (dispatch, {softwareProductId, componentId, formData}) => {
+	RestAPIUtil.create(snmpTrapUrl(softwareProductId, componentId, UPLOAD), formData).then(()=> dispatch({
+		type: actionTypes.SNMP_TRAP_UPLOADED, data: {filename: formData.get('upload').name}
+	}));
+};
+
+let uploadSnmpPollFile = (dispatch, {softwareProductId, componentId, formData}) => {
+	RestAPIUtil.create(snmpPollUrl(softwareProductId, componentId, UPLOAD), formData).then(()=> dispatch({
+		type: actionTypes.SNMP_POLL_UPLOADED, data: {filename: formData.get('upload').name}
+	}));
+};
+
+let deleteSnmpTrapFile = (dispatch, {softwareProductId, componentId}) => {
+	RestAPIUtil.destroy(snmpTrapUrl(softwareProductId, componentId, !UPLOAD)).then(()=> dispatch({
+		type: actionTypes.SNMP_TRAP_DELETED
+	}));
+};
+
+let deleteSnmpPollFile = (dispatch, {softwareProductId, componentId}) => {
+	RestAPIUtil.destroy(snmpPollUrl(softwareProductId, componentId, !UPLOAD)).then(()=> dispatch({
+		type: actionTypes.SNMP_POLL_DELETED
+	}));
+};
+
+const SoftwareProductComponentsMonitoringAction = {
+
+	fetchExistingFiles(dispatch, {softwareProductId, componentId}){
+		RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/snmp`).then(response =>
+			dispatch({
+				type: actionTypes.SNMP_FILES_DATA_CHANGE,
+				data: {trapFilename: response.snmpTrap, pollFilename: response.snmpPoll}
+			})
+		);
+	},
+
+	uploadSnmpFile(dispatch, {softwareProductId, componentId, formData, type}){
+		if (formData.get('upload').size) {
+			if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
+				uploadSnmpTrapFile(dispatch, {softwareProductId, componentId, formData});
+			}
+			else {
+				uploadSnmpPollFile(dispatch, {softwareProductId, componentId, formData});
+			}
+		}
+		else {
+			onInvalidFileSizeUpload(dispatch);
+		}
+	},
+
+	deleteSnmpFile(dispatch, {softwareProductId, componentId, type}){
+		if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
+			deleteSnmpTrapFile(dispatch, {softwareProductId, componentId});
+		}
+		else {
+			deleteSnmpPollFile(dispatch, {softwareProductId, componentId});
+		}
+	}
+
+};
+
+export default SoftwareProductComponentsMonitoringAction;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js
new file mode 100644
index 0000000..eeececb
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+
+	SNMP_FILES_DATA_CHANGE: null,
+
+	SNMP_TRAP_UPLOADED: null,
+	SNMP_POLL_UPLOADED: null,
+
+	SNMP_TRAP_DELETED: null,
+	SNMP_POLL_DELETED: null
+});
+
+export default keyMirror({
+	SNMP_TRAP: null,
+	SNMP_POLL: null
+});
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js
new file mode 100644
index 0000000..72e0a85
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.SNMP_FILES_DATA_CHANGE:
+			return {
+				...state,
+				trapFilename: action.data.trapFilename,
+				pollFilename: action.data.pollFilename
+			};
+		case actionTypes.SNMP_TRAP_UPLOADED:
+			return {
+				...state,
+				trapFilename: action.data.filename
+			};
+		case actionTypes.SNMP_POLL_UPLOADED:
+			return {
+				...state,
+				pollFilename: action.data.filename
+			};
+		case actionTypes.SNMP_TRAP_DELETED:
+			return {
+				...state,
+				trapFilename: undefined
+			};
+		case actionTypes.SNMP_POLL_DELETED:
+			return {
+				...state,
+				pollFilename: undefined
+			};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx
new file mode 100644
index 0000000..ca090c5
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx
@@ -0,0 +1,117 @@
+import React, {Component, PropTypes} from 'react';
+import Dropzone from 'react-dropzone';
+import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js';
+import ButtonToolbar from 'react-bootstrap/lib/ButtonToolbar.js';
+import Button from 'react-bootstrap/lib/Button.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import SoftwareProductComponentsMonitoringConstants from './SoftwareProductComponentsMonitoringConstants.js';
+
+class SoftwareProductComponentsMonitoringView extends Component {
+
+	static propTypes = {
+		isReadOnlyMode: PropTypes.bool,
+		trapFilename: PropTypes.string,
+		pollFilename: PropTypes.string,
+		softwareProductId: PropTypes.string,
+
+		onDropMibFileToUpload: PropTypes.func,
+		onDeleteSnmpFile: PropTypes.func
+	};
+
+	state = {
+		dragging: false
+	};
+
+
+	render() {
+		return (
+			<div className='vsp-component-monitoring'>
+				{this.renderDropzoneWithType(SoftwareProductComponentsMonitoringConstants.SNMP_TRAP)}
+				{this.renderDropzoneWithType(SoftwareProductComponentsMonitoringConstants.SNMP_POLL)}
+			</div>
+		);
+	}
+
+	renderDropzoneWithType(type) {
+		let {isReadOnlyMode, trapFilename, pollFilename} = this.props;
+		let fileName;
+		if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
+			fileName = trapFilename;
+		}
+		else {
+			fileName = pollFilename;
+		}
+		let refAndName = `fileInput${type.toString()}`;
+		let typeDisplayName = this.getFileTypeDisplayName(type);
+		return (
+			<Dropzone
+				className={`snmp-dropzone ${this.state.dragging ? 'active-dragging' : ''}`}
+				onDrop={files => this.handleImport(files, {isReadOnlyMode, type, refAndName})}
+				onDragEnter={() => this.handleOnDragEnter(isReadOnlyMode)}
+				onDragLeave={() => this.setState({dragging:false})}
+				multiple={false}
+				disableClick={true}
+				ref={refAndName}
+				name={refAndName}
+				accept='.zip'
+				disabled>
+				<div className='draggable-wrapper'>
+					<div className='section-title'>{typeDisplayName}</div>
+					{fileName ? this.renderUploadedFileName(fileName, type) : this.renderUploadButton(refAndName)}
+				</div>
+			</Dropzone>
+		);
+	}
+
+	renderUploadButton(refAndName) {
+		let {isReadOnlyMode} = this.props;
+		return (
+			<div
+				className={`software-product-landing-view-top-block-col-upl${isReadOnlyMode ? ' disabled' : ''}`}>
+				<div className='drag-text'>{i18n('Drag & drop for upload')}</div>
+				<div className='or-text'>{i18n('or')}</div>
+				<div className='upload-btn primary-btn' onClick={() => this.refs[refAndName].open()}>
+					<span className='primary-btn-text'>{i18n('Select file')}</span>
+				</div>
+			</div>
+		);
+	}
+
+	renderUploadedFileName(filename, type) {
+		return (
+			<ButtonToolbar>
+				<ButtonGroup>
+					<Button disabled>{filename}</Button>
+					<Button className='delete-button' onClick={()=>this.props.onDeleteSnmpFile(type)}>X</Button>
+				</ButtonGroup>
+			</ButtonToolbar>
+		);
+	}
+
+
+	handleOnDragEnter(isReadOnlyMode) {
+		if (!isReadOnlyMode) {
+			this.setState({dragging: true});
+		}
+	}
+
+	handleImport(files, {isReadOnlyMode, type, refAndName}) {
+		if (isReadOnlyMode) {
+			return;
+		}
+
+		this.setState({dragging: false});
+		let file = files[0];
+		let formData = new FormData();
+		formData.append('upload', file);
+		this.refs[refAndName].value = '';
+		this.props.onDropMibFileToUpload(formData, type);
+	}
+
+	getFileTypeDisplayName(type) {
+		return type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP ? 'SNMP Trap' : 'SNMP Poll';
+	}
+
+}
+
+export default SoftwareProductComponentsMonitoringView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js
new file mode 100644
index 0000000..a412456
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentsNetworkActionHelper from './SoftwareProductComponentsNetworkActionHelper.js';
+import SoftwareProductComponentsNICEditorView from './SoftwareProductComponentsNICEditorView.jsx';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+export const mapStateToProps = ({softwareProduct}) => {
+
+	let {softwareProductEditor: {data:currentSoftwareProduct = {},  isValidityData = true}, softwareProductComponents} = softwareProduct;
+
+	let {network: {nicEditor = {}}} = softwareProductComponents;
+	let {data, qdata, qschema} = nicEditor;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+
+	return {
+		currentSoftwareProduct,
+		isValidityData,
+		data,
+		qdata,
+		qschema,
+		isReadOnlyMode
+	};
+
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+	return {
+		onDataChanged: deltaData => SoftwareProductComponentsNetworkActionHelper.updateNICData(dispatch, {deltaData}),
+		onSubmit: ({data, qdata}) => SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(dispatch, {softwareProductId, componentId, data, qdata}),
+		onCancel: () => SoftwareProductComponentsNetworkActionHelper.closeNICEditor(dispatch),
+		onQDataChanged: ({data}) => SoftwareProductComponentsNetworkActionHelper.updateNICQuestionnaire(dispatch, {data})
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(SoftwareProductComponentsNICEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js
new file mode 100644
index 0000000..d49f9cc
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.NICEditor.OPEN:
+			return {
+				...state,
+				data: action.nic
+			};
+		case actionTypes.NICEditor.CLOSE:
+			return {};
+		case actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE:
+			return {
+				...state,
+				qdata: action.payload.qdata || state.qdata,
+				qschema: action.payload.qschema || state.qschema
+			};
+		case actionTypes.NICEditor.DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx
new file mode 100644
index 0000000..7393a83
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx
@@ -0,0 +1,322 @@
+import React from 'react';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+
+class SoftwareProductComponentsNetworkEditorView extends React.Component {
+
+	render() {
+		let {onCancel, isReadOnlyMode} = this.props;
+		return (
+			<ValidationForm
+				ref='validationForm'
+				hasButtons={true}
+				onSubmit={ () => this.submit() }
+				onReset={ () => onCancel() }
+				labledButtons={true}
+				isReadOnlyMode={isReadOnlyMode}
+				className='vsp-components-network-editor'>
+				{this.renderEditorFields()}
+			</ValidationForm>
+		);
+	}
+
+	renderEditorFields() {
+		let {data = {}, qdata = {}, qschema = {}, onQDataChanged, onDataChanged, isReadOnlyMode} = this.props;
+		let {name, description, networkName} = data;
+		let netWorkValues = [{
+			enum: networkName,
+			title: networkName
+		}];
+		return(
+			<div className='editor-data'>
+				<div className='row'>
+					<div className='col-md-6'>
+						<ValidationInput
+							label={i18n('Name')}
+							value={name}
+							disabled={true}
+							type='text'/>
+					</div>
+					<div className='col-md-6'>
+						<ValidationInput
+							label={i18n('Purpose of NIC')}
+							value={description}
+							onChange={description => onDataChanged({description})}
+							disabled={isReadOnlyMode}
+							type='textarea'/>
+					</div>
+				</div>
+				<ValidationForm
+					onDataChanged={onQDataChanged}
+					data={qdata}
+					schema={qschema}
+					isReadOnlyMode={isReadOnlyMode}
+					hasButtons={false}>
+					<div className='row'>
+						<div className='part-title'>{i18n('Protocols')}</div>
+						<div className='col-md-6'>
+							<ValidationInput
+								label={i18n('Protocols')}
+								type='select'
+								pointer='/protocols/protocols'/>
+						</div>
+						<div className='col-md-6'>
+							<ValidationInput
+								label={i18n('Protocol with Highest Traffic Profile')}
+								type='select'
+								pointer='/protocols/protocolWithHighestTrafficProfile'/>
+						</div>
+					</div>
+					<div className='row'>
+						<div className='part-title'>{i18n('IP Configuration')}</div>
+						<div className='col-md-3'>
+							<ValidationInput
+								label={i18n('IPv4 Required')}
+								type='checkbox'
+								pointer='/ipConfiguration/ipv4Required'/>
+						</div>
+						<div className='col-md-9'>
+							<ValidationInput
+								label={i18n('IPv6 Required')}
+								type='checkbox'
+								pointer='/ipConfiguration/ipv6Required'/>
+						</div>
+					</div>
+				</ValidationForm>
+				<div className='row'>
+					<div className='part-title'>{i18n('Network')}</div>
+					<div className='col-md-2'>
+						<ValidationInput
+							label={i18n('Internal')}
+							disabled
+							checked={true}
+							className='network-radio disabled'
+							type='radio'/>
+					</div>
+					<div className='col-md-4'>
+						<ValidationInput
+							label={i18n('External')}
+							disabled
+							checked={false}
+							className='network-radio disabled'
+							type='radio'/>
+					</div>
+					<div className='col-md-6'>
+						<ValidationInput
+							label={i18n('Network')}
+							type='select'
+							disabled={true}
+							values={netWorkValues}/>
+					</div>
+				</div>
+				<ValidationForm
+					onDataChanged={onQDataChanged}
+					data={qdata}
+					schema={qschema}
+					isReadOnlyMode={isReadOnlyMode}
+					hasButtons={false}>
+					<div className='row'>
+						<div className='part-title'>{i18n('Sizing')}</div>
+						<div className='col-md-12'>
+							<ValidationInput
+								label={i18n('Describe Quality of Service')}
+								type='textarea'
+								pointer='/sizing/describeQualityOfService'/>
+						</div>
+					</div>
+
+					<div className='row'>
+						<div className='part-title'>{i18n('Inflow Traffic per second')}</div>
+					</div>
+
+					<div className='row'>
+						<div className='col-md-6'>
+							<div className='row'>
+								<div className='part-title-small'>{i18n('Packets')}</div>
+							</div>
+							<div className='row'>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Peak')}
+										type='text'
+										pointer='/sizing/inflowTrafficPerSecond/packets/peak'/>
+								</div>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Avg')}
+										type='text'
+										pointer='/sizing/inflowTrafficPerSecond/packets/avg'/>
+								</div>
+							</div>
+						</div>
+						<div className='col-md-6'>
+							<div className='row'>
+								<div className='part-title-small'>{i18n('Bytes')}</div>
+							</div>
+							<div className='row'>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Peak')}
+										type='text'
+										pointer='/sizing/inflowTrafficPerSecond/bytes/peak'/>
+
+								</div>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Avg')}
+										type='text'
+										pointer='/sizing/inflowTrafficPerSecond/bytes/avg'/>
+								</div>
+							</div>
+						</div>
+					</div>
+
+					<div className='row'>
+						<div className='part-title'>{i18n('Outflow Traffic per second')}</div>
+					</div>
+
+					<div className='row'>
+						<div className='col-md-6'>
+							<div className='row'>
+								<div className='part-title-small'>{i18n('Packets')}</div>
+							</div>
+							<div className='row'>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Peak')}
+										type='text'
+										pointer='/sizing/outflowTrafficPerSecond/packets/peak'/>
+								</div>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Avg')}
+										type='text'
+										pointer='/sizing/outflowTrafficPerSecond/packets/avg'/>
+
+								</div>
+							</div>
+						</div>
+						<div className='col-md-6'>
+							<div className='row'>
+								<div className='part-title-small'>{i18n('Bytes')}</div>
+							</div>
+							<div className='row'>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Peak')}
+										type='text'
+										pointer='/sizing/outflowTrafficPerSecond/bytes/peak'/>
+
+								</div>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Avg')}
+										type='text'
+										pointer='/sizing/outflowTrafficPerSecond/bytes/avg'/>
+
+								</div>
+							</div>
+						</div>
+					</div>
+
+					<div className='row'>
+						<div className='part-title'>{i18n('Flow Length')}</div>
+					</div>
+
+					<div className='row'>
+						<div className='col-md-6'>
+							<div className='row'>
+								<div className='part-title-small'>{i18n('Packets')}</div>
+							</div>
+							<div className='row'>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Peak')}
+										type='text'
+										pointer='/sizing/flowLength/packets/peak'/>
+								</div>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Avg')}
+										type='text'
+										pointer='/sizing/flowLength/packets/avg'/>
+								</div>
+							</div>
+						</div>
+						<div className='col-md-6'>
+							<div className='row'>
+								<div className='part-title-small'>{i18n('Bytes')}</div>
+							</div>
+							<div className='row'>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Peak')}
+										type='text'
+										pointer='/sizing/flowLength/bytes/peak'/>
+
+								</div>
+								<div className='col-md-6'>
+									<ValidationInput
+										label={i18n('Avg')}
+										type='text'
+										pointer='/sizing/flowLength/bytes/avg'/>
+								</div>
+							</div>
+						</div>
+					</div>
+
+					<div className='row'>
+						<div className='col-md-9'>
+							<div className='row'>
+								<div className='part-title-small'>{i18n('Acceptable Jitter')}</div>
+							</div>
+							<div className='row'>
+								<div className='col-md-4'>
+									<ValidationInput
+										label={i18n('Min')}
+										type='text'
+										pointer='/sizing/acceptableJitter/mean'/>
+								</div>
+								<div className='col-md-4'>
+									<ValidationInput
+										label={i18n('Max')}
+										type='text'
+										pointer='/sizing/acceptableJitter/max'/>
+								</div>
+								<div className='col-md-4'>
+									<ValidationInput
+										label={i18n('Var')}
+										type='text'
+										pointer='/sizing/acceptableJitter/variable'/>
+								</div>
+							</div>
+						</div>
+						<div className='col-md-3'>
+							<div className='row'>
+								<div className='part-title-small'>{i18n('Acceptable Packet Loss %')}</div>
+							</div>
+							<div className='row'>
+								<div className='col-md-12'>
+									<ValidationInput
+										label={i18n('In Percent')}
+										type='text'
+										pointer='/sizing/acceptablePacketLoss'/>
+								</div>
+							</div>
+						</div>
+					</div>
+				</ValidationForm>
+			</div>
+
+		);
+	}
+	submit() {
+		let {data, qdata, onSubmit} = this.props;
+		onSubmit({data, qdata});
+	}
+}
+
+export default SoftwareProductComponentsNetworkEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js
new file mode 100644
index 0000000..bc53e1a
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js';
+
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.NIC_LIST_UPDATE:
+			return [...action.response];
+		case actionTypes.NIC_LIST_EDIT:
+			const indexForEdit = state.findIndex(nic => nic.id === action.nic.id);
+			return [...state.slice(0, indexForEdit), action.nic, ...state.slice(indexForEdit + 1)];
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js
new file mode 100644
index 0000000..8ff6b50
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js
@@ -0,0 +1,129 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+
+import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js';
+
+function baseUrl(softwareProductId, componentId) {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/nics`;
+}
+
+
+function fetchNICQuestionnaire({softwareProductId, componentId, nicId, version}) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/${nicId}/questionnaire${versionQuery}`);
+}
+
+function fetchNIC({softwareProductId, componentId, nicId, version}) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/${nicId}${versionQuery}`);
+}
+
+function fetchNICsList({softwareProductId, componentId, version}) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}${versionQuery}`);
+}
+
+function saveNIC({softwareProductId, componentId, nic: {id, name, description, networkId}}) {
+	return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${id}`,{
+		name,
+		description,
+		networkId
+	});
+}
+
+function saveNICQuestionnaire({softwareProductId, componentId, nicId, qdata}) {
+	return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${nicId}/questionnaire`, qdata);
+}
+
+const SoftwareProductComponentNetworkActionHelper = {
+
+	fetchNICsList(dispatch, {softwareProductId, componentId, version}) {
+		return fetchNICsList({softwareProductId, componentId, version}).then((response) => {
+			dispatch({
+				type: actionTypes.NIC_LIST_UPDATE,
+				response: response.results
+			});
+		});
+	},
+
+	openNICEditor(dispatch, {nic = {}, data = {}}) {
+		dispatch({
+			type: actionTypes.NICEditor.OPEN,
+			nic: {...data, id: nic.id}
+		});
+	},
+
+	closeNICEditor(dispatch) {
+		dispatch({
+			type: actionTypes.NICEditor.CLOSE
+		});
+	},
+
+	loadNICData({softwareProductId, componentId, nicId, version}) {
+		return fetchNIC({softwareProductId, componentId, nicId, version});
+	},
+
+	loadNICQuestionnaire(dispatch, {softwareProductId, componentId, nicId, version}) {
+		return fetchNICQuestionnaire({softwareProductId, componentId, nicId, version}).then((response) => {
+			dispatch({
+				type: actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE,
+				payload: {
+					qdata: response.data ? JSON.parse(response.data) : {},
+					qschema: JSON.parse(response.schema)
+				}
+			});
+		});
+	},
+
+	updateNICData(dispatch, {deltaData}) {
+		dispatch({
+			type: actionTypes.NICEditor.DATA_CHANGED,
+			deltaData
+		});
+	},
+
+	updateNICQuestionnaire(dispatch, {data}) {
+		dispatch({
+			type: actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE,
+			payload: {
+				qdata: data
+			}
+		});
+	},
+
+	saveNICDataAndQuestionnaire(dispatch, {softwareProductId, componentId, data, qdata}) {
+		SoftwareProductComponentNetworkActionHelper.closeNICEditor(dispatch);
+		return Promise.all([
+			saveNICQuestionnaire({softwareProductId, componentId, nicId: data.id, qdata}),
+			saveNIC({softwareProductId, componentId, nic: data}).then(() => {
+				dispatch({
+					type: actionTypes.NIC_LIST_EDIT,
+					nic: data
+				});
+			})
+		]);
+	}
+};
+
+export default SoftwareProductComponentNetworkActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js
new file mode 100644
index 0000000..193f4b2
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	NIC_LIST_EDIT: null,
+	NIC_LIST_UPDATE: null,
+
+	NICEditor: {
+		OPEN: null,
+		CLOSE: null,
+		NIC_QUESTIONNAIRE_UPDATE: null,
+		DATA_CHANGED: null
+	}
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js
new file mode 100644
index 0000000..9172dc6
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
+import SoftwareProductComponentsNetworkListView from './SoftwareProductComponentsNetworkListView.jsx';
+import SoftwareProductComponentsNetworkActionHelper from './SoftwareProductComponentsNetworkActionHelper.js';
+
+
+export const mapStateToProps = ({softwareProduct}) => {
+
+	let {softwareProductEditor: {data: currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct;
+	let {network: {nicEditor = {}, nicList = []}, componentEditor: {data: componentData, qdata, qschema}} = softwareProductComponents;
+	let {data} = nicEditor;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+	let {version} = currentSoftwareProduct;
+	let manualMode = nicList.length <= 0;
+	let isModalInEditMode = true;
+
+	return {
+		version,
+		componentData,
+		qdata,
+		qschema,
+		isValidityData,
+		nicList,
+		isDisplayModal: Boolean(data),
+		isModalInEditMode,
+		manualMode,
+		isReadOnlyMode
+	};
+
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+	return {
+		onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+		onAddNIC: () => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch),
+		onEditNicClick: (nic, version) => {
+			Promise.all([
+				SoftwareProductComponentsNetworkActionHelper.loadNICData({
+					softwareProductId,
+					componentId,
+					nicId: nic.id,
+					version
+				}),
+				SoftwareProductComponentsNetworkActionHelper.loadNICQuestionnaire(dispatch, {
+					softwareProductId,
+					componentId,
+					nicId: nic.id,
+					version
+				})
+			]).then(
+				([{data}]) => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch, {nic, data})
+			);
+		},
+		onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch,
+			{softwareProductId,
+			vspComponentId: componentId,
+			qdata});
+		}
+
+
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsNetworkListView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx
new file mode 100644
index 0000000..b3e17ff
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx
@@ -0,0 +1,136 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+
+import SoftwareProductComponentsNICEditor from './SoftwareProductComponentsNICEditor.js';
+
+class SoftwareProductComponentsNetworkView extends React.Component {
+
+	state = {
+		localFilter: ''
+	};
+
+	render() {
+		let {qdata, qschema, onQDataChanged, isModalInEditMode, isDisplayModal, softwareProductId, componentId, isReadOnlyMode} = this.props;
+
+		return(
+			<div className='vsp-components-network'>
+				<div className='network-data'>
+					<div>
+						<ValidationForm
+							onDataChanged={onQDataChanged}
+							data={qdata}
+							isReadOnlyMode={isReadOnlyMode}
+							schema={qschema}
+							hasButtons={false}>
+							<h3 className='section-title'>{i18n('Network Capacity')}</h3>
+							<div className='rows-section'>
+								<div className='row-flex-components input-row'>
+									<div className='single-col'>
+										<ValidationInput
+											label={i18n('Protocol with Highest Traffic Profile across all NICs')}
+											type='select'
+											pointer='/network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs'/>
+									</div>
+									<div className='single-col add-line-break'>
+										<ValidationInput
+											label={i18n('Network Transactions per Second')}
+											type='text'
+											pointer='/network/networkCapacity/networkTransactionsPerSecond'/>
+									</div>
+									<div className='empty-two-col' />
+								</div>
+							</div>
+
+						</ValidationForm>
+					</div>
+					{this.renderNicList()}
+				</div>
+				<Modal show={isDisplayModal} bsSize='large' animation={true} className='network-nic-modal'>
+					<Modal.Header>
+						<Modal.Title>{isModalInEditMode ? i18n('Edit NIC') : i18n('Create New NIC')}</Modal.Title>
+					</Modal.Header>
+					<Modal.Body>
+						{
+							<SoftwareProductComponentsNICEditor
+								softwareProductId={softwareProductId}
+								componentId={componentId}
+								isReadOnlyMode={isReadOnlyMode}/>
+						}
+					</Modal.Body>
+				</Modal>
+			</div>
+		);
+	}
+
+	renderNicList() {
+		const {localFilter} = this.state;
+		let {onAddNIC, manualMode, isReadOnlyMode} = this.props;
+		let onAdd = manualMode ? onAddNIC : false;
+		return (
+			<ListEditorView
+				title={i18n('Interfaces')}
+				plusButtonTitle={i18n('Add NIC')}
+				filterValue={localFilter}
+				placeholder={i18n('Filter NICs by Name')}
+				onAdd={onAdd}
+				isReadOnlyMode={isReadOnlyMode}
+				onFilter={filter => this.setState({localFilter: filter})}>
+				{!manualMode && this.filterList().map(nic => this.renderNicListItem(nic, isReadOnlyMode))}
+			</ListEditorView>
+		);
+	}
+
+	renderNicListItem(nic, isReadOnlyMode) {
+		let {id, name, description, networkName = ''} = nic;
+		let {onEditNicClick, version} =  this.props;
+		return (
+			<ListEditorItemView
+				key={id}
+				className='list-editor-item-view'
+				isReadOnlyMode={isReadOnlyMode}
+				onSelect={() => onEditNicClick(nic, version)}>
+
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Name')}</div>
+					<div className='name'>{name}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Purpose of NIC')}</div>
+					<div className='description'>{description}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Network')}</div>
+					<div className='artifact-name'>{networkName}</div>
+				</div>
+
+			</ListEditorItemView>
+		);
+	}
+
+	filterList() {
+		let {nicList} = this.props;
+		let {localFilter} = this.state;
+		if (localFilter.trim()) {
+			const filter = new RegExp(escape(localFilter), 'i');
+			return nicList.filter(({name = '', description = ''}) => {
+				return escape(name).match(filter) || escape(description).match(filter);
+			});
+		}
+		else {
+			return nicList;
+		}
+	}
+
+	save() {
+		let {onSubmit, qdata} = this.props;
+		return onSubmit({qdata});
+	}
+}
+
+export default SoftwareProductComponentsNetworkView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js
new file mode 100644
index 0000000..d535a34
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js
@@ -0,0 +1,145 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import {actionTypes} from './SoftwareProductComponentProcessesConstants.js';
+
+function baseUrl(softwareProductId, componentId) {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/processes`;
+}
+
+function fetchProcessesList({softwareProductId, componentId, version}) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}${versionQuery}`);
+}
+
+function deleteProcess({softwareProductId, componentId, processId}) {
+	return RestAPIUtil.destroy(`${baseUrl(softwareProductId, componentId)}/${processId}`);
+}
+
+function putProcess({softwareProductId, componentId, process}) {
+	return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${process.id}`, {
+		name: process.name,
+		description: process.description
+	});
+}
+
+function postProcess({softwareProductId,componentId, process}) {
+	return RestAPIUtil.create(`${baseUrl(softwareProductId, componentId)}`, {
+		name: process.name,
+		description: process.description
+	});
+}
+
+function uploadFileToProcess({softwareProductId, processId, componentId, formData}) {
+	return RestAPIUtil.create(`${baseUrl(softwareProductId, componentId)}/${processId}/upload`, formData);
+}
+
+
+
+const SoftwareProductComponentProcessesActionHelper = {
+	fetchProcessesList(dispatch, {softwareProductId, componentId, version}) {
+		dispatch({
+			type: actionTypes.FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES,
+			processesList: []
+		});
+
+		return fetchProcessesList({softwareProductId, componentId, version}).then(response => {
+			dispatch({
+				type: actionTypes.FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES,
+				processesList: response.results
+			});
+		});
+	},
+
+	deleteProcess(dispatch, {process, softwareProductId, componentId}) {
+		return deleteProcess({softwareProductId, processId:process.id, componentId}).then(() => {
+			dispatch({
+				type: actionTypes.DELETE_SOFTWARE_PRODUCT_COMPONENTS_PROCESS,
+				processId: process.id
+			});
+		});
+
+	},
+
+	saveProcess(dispatch, {softwareProductId, componentId, previousProcess, process}) {
+		if (previousProcess) {
+			return putProcess({softwareProductId,componentId,  process}).then(() => {
+				if (process.formData && process.formData.name !== previousProcess.artifactName){
+					uploadFileToProcess({softwareProductId, processId: process.id, formData: process.formData, componentId});
+				}
+				dispatch({
+					type: actionTypes.EDIT_SOFTWARE_PRODUCT_COMPONENTS_PROCESS,
+					process
+				});
+			});
+		}
+		else {
+			return postProcess({softwareProductId, componentId, process}).then(response => {
+				if (process.formData) {
+					uploadFileToProcess({softwareProductId, processId: response.value, formData: process.formData, componentId});
+				}
+				dispatch({
+					type: actionTypes.ADD_SOFTWARE_PRODUCT_COMPONENTS_PROCESS,
+					process: {
+						...process,
+						id: response.value
+					}
+				});
+			});
+		}
+	},
+
+	hideDeleteConfirm(dispatch) {
+		dispatch({
+			type: actionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM,
+			processToDelete: false
+		});
+	},
+
+	openDeleteProcessesConfirm(dispatch, {process} ) {
+		dispatch({
+			type: actionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM,
+			processToDelete: process
+		});
+	},
+
+	openEditor(dispatch, process = {}) {
+		dispatch({
+			type: actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_OPEN,
+			process
+		});
+	},
+	closeEditor(dispatch) {
+		dispatch({
+			type:actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE
+		});
+	},
+	processEditorDataChanged(dispatch, {deltaData}) {
+		dispatch({
+			type: actionTypes.processEditor.DATA_CHANGED,
+			deltaData
+		});
+	}
+};
+
+export default SoftwareProductComponentProcessesActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js
new file mode 100644
index 0000000..78a111a
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	ADD_SOFTWARE_PRODUCT_COMPONENTS_PROCESS: null,
+	EDIT_SOFTWARE_PRODUCT_COMPONENTS_PROCESS: null,
+	DELETE_SOFTWARE_PRODUCT_COMPONENTS_PROCESS: null,
+	SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_OPEN: null,
+	SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE: null,
+	FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES: null,
+	SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM: null,
+	processEditor: {
+		DATA_CHANGED: null
+	}
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js
new file mode 100644
index 0000000..0138023
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper';
+import SoftwareProductComponentProcessesEditorView from './SoftwareProductComponentProcessesEditorView.jsx';
+
+const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductComponents: {componentProcesses = {}}} = softwareProduct;
+	let {processesList = [], processesEditor = {}} = componentProcesses;
+	let {data} = processesEditor;
+
+	let previousData;
+	const processId = data ? data.id : null;
+	if(processId) {
+		previousData = processesList.find(process => process.id === processId);
+	}
+
+	return {
+		data,
+		previousData
+	};
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+
+	return {
+		onDataChanged: deltaData => SoftwareProductComponentProcessesActionHelper.processEditorDataChanged(dispatch, {deltaData}),
+		onCancel: () => SoftwareProductComponentProcessesActionHelper.closeEditor(dispatch),
+		onSubmit: ({previousProcess, process}) => {
+			SoftwareProductComponentProcessesActionHelper.closeEditor(dispatch);
+			SoftwareProductComponentProcessesActionHelper.saveProcess(dispatch, {softwareProductId, previousProcess, componentId, process});
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(SoftwareProductComponentProcessesEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js
new file mode 100644
index 0000000..f859f69
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentProcessesConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_OPEN:
+			return {
+				...state,
+				data: action.process
+			};
+		case actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE:
+			return {};
+
+		case actionTypes.processEditor.DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx
new file mode 100644
index 0000000..ca6d843
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx
@@ -0,0 +1,124 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Dropzone from 'react-dropzone';
+
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+
+const SoftwareProductProcessEditorPropType = React.PropTypes.shape({
+	id: React.PropTypes.string,
+	name: React.PropTypes.string,
+	description: React.PropTypes.string,
+	artifactName: React.PropTypes.string
+});
+
+class SoftwareProductProcessesEditorView extends React.Component {
+
+	state = {
+		dragging: false,
+		files: []
+	};
+
+	static propTypes = {
+		data: SoftwareProductProcessEditorPropType,
+		previousData: SoftwareProductProcessEditorPropType,
+		isReadOnlyMode: React.PropTypes.bool,
+		onDataChanged: React.PropTypes.func,
+		onSubmit: React.PropTypes.func,
+		onCancel: React.PropTypes.func
+	};
+
+	render() {
+		let {isReadOnlyMode, onCancel, onDataChanged, data = {}} = this.props;
+		let {name, description, artifactName} = data;
+
+		return (
+			<div>
+				<ValidationForm
+					ref='validationForm'
+					isReadOnlyMode={isReadOnlyMode}
+					hasButtons={true}
+					labledButtons={true}
+					onSubmit={ () => this.submit() }
+					onReset={ () => onCancel() }
+					className='vsp-processes-editor'>
+				<div className={`vsp-processes-editor-data${isReadOnlyMode ? ' disabled' : '' }`}>
+					<Dropzone
+						className={`vsp-process-dropzone-view ${this.state.dragging ? 'active-dragging' : ''}`}
+						onDrop={files => this.handleImportSubmit(files)}
+						onDragEnter={() => this.setState({dragging:true})}
+						onDragLeave={() => this.setState({dragging:false})}
+						multiple={false}
+						disableClick={true}
+						ref='processEditorFileInput'
+						name='processEditorFileInput'
+						accept='*.*'>
+						<div className='row'>
+							<div className='col-md-6'>
+								<ValidationInput
+									onChange={name => onDataChanged({name})}
+									label={i18n('Name')}
+									value={name}
+									validations={{validateName: true, maxLength: 120, required: true}}
+									type='text'/>
+								<ValidationInput
+									label={i18n('Artifacts')}
+									value={artifactName}
+									type='text'
+									disabled/>
+							</div>
+							<div className='col-md-6'>
+									<div className='file-upload-box'>
+										<div className='drag-text'>{i18n('Drag & drop for upload')}</div>
+										<div className='or-text'>{i18n('or')}</div>
+										<div className='upload-btn primary-btn' onClick={() => this.refs.processEditorFileInput.open()}>
+											<span className='primary-btn-text'>{i18n('Select file')}</span>
+										</div>
+									</div>
+							</div>
+						</div>
+						<ValidationInput
+							onChange={description => onDataChanged({description})}
+							label={i18n('Notes')}
+							value={description}
+							name='vsp-process-description'
+							className='vsp-process-description'
+							validations={{maxLength: 1000}}
+							type='textarea'/>
+					</Dropzone>
+				</div>
+			</ValidationForm>
+			</div>
+		);
+	}
+
+	submit() {
+		const {data: process, previousData: previousProcess} = this.props;
+		let {files} = this.state;
+		let formData = new FormData();
+		if (files.length) {
+			let file = files[0];
+			formData.append('upload', file);
+		}
+
+		let updatedProcess = {
+			...process,
+			formData: files.length ? formData : false
+		};
+		this.props.onSubmit({process: updatedProcess, previousProcess});
+	}
+
+
+	handleImportSubmit(files) {
+		let {onDataChanged} = this.props;
+		this.setState({
+			dragging: false,
+			complete: '0',
+			files
+		});
+		onDataChanged({artifactName: files[0].name});
+	}
+}
+
+export default SoftwareProductProcessesEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js
new file mode 100644
index 0000000..5f69328
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper.js';
+
+import SoftwareProductComponentsProcessesListView from './SoftwareProductComponentsProcessesListView.jsx';
+
+const mapStateToProps = ({softwareProduct}) => {
+
+	let {softwareProductEditor: {data:currentSoftwareProduct = {},  isValidityData = true}, softwareProductComponents: {componentProcesses = {}}} = softwareProduct;
+	let{processesList = [], processesEditor = {}} = componentProcesses;
+	let {data} = processesEditor;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+
+	return {
+		currentSoftwareProduct,
+		isValidityData,
+		processesList,
+		isDisplayModal: Boolean(data),
+		isModalInEditMode: Boolean(data && data.id),
+		isReadOnlyMode
+	};
+
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId}) => {
+
+	return {
+		onAddProcess: () => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch),
+		onEditProcessClick: (process) => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch, process),
+		onDeleteProcessClick: (process) => SoftwareProductComponentProcessesActionHelper.openDeleteProcessesConfirm(dispatch, {process, softwareProductId})
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsProcessesListView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js
new file mode 100644
index 0000000..4bb124d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductComponentProcessesConstants.js';
+
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES:
+			return [...action.processesList];
+		case actionTypes.EDIT_SOFTWARE_PRODUCT_COMPONENTS_PROCESS:
+			const indexForEdit = state.findIndex(process => process.id === action.process.id);
+			return [...state.slice(0, indexForEdit), action.process, ...state.slice(indexForEdit + 1)];
+		case actionTypes.ADD_SOFTWARE_PRODUCT_COMPONENTS_PROCESS:
+			return [...state, action.process];
+		case actionTypes.DELETE_SOFTWARE_PRODUCT_COMPONENTS_PROCESS:
+			return state.filter(process => process.id !== action.processId);
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx
new file mode 100644
index 0000000..48fa862
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx
@@ -0,0 +1,45 @@
+import React from 'react';
+import {connect} from 'react-redux';
+import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
+import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+function renderMsg(processToDelete) {
+	let name = processToDelete ? processToDelete.name : '';
+	let msg = i18n('Are you sure you want to delete "{name}"?', {name});
+	return (
+		<div>
+			<p>{msg}</p>
+		</div>
+	);
+};
+
+const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductEditor, softwareProductComponents} = softwareProduct;
+	let {componentProcesses} = softwareProductComponents;
+	let {processToDelete} = componentProcesses;
+	let softwareProductId = softwareProductEditor.data.id;
+	const show = processToDelete !== false;
+	return {
+		show,
+		title: 'Warning!',
+		type: 'warning',
+		msg: renderMsg(processToDelete),
+		confirmationDetails: {processToDelete, softwareProductId}
+	};
+};
+
+const mapActionsToProps = (dispatch,{componentId, softwareProductId}) => {
+	return {
+		onConfirmed: ({processToDelete}) => {
+			SoftwareProductComponentProcessesActionHelper.deleteProcess(dispatch, {process: processToDelete, softwareProductId, componentId});
+			SoftwareProductComponentProcessesActionHelper.hideDeleteConfirm(dispatch);
+		},
+		onDeclined: () => {
+			SoftwareProductComponentProcessesActionHelper.hideDeleteConfirm(dispatch);
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx
new file mode 100644
index 0000000..a8b07e9
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx
@@ -0,0 +1,125 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+
+import SoftwareProductProcessesEditor from './SoftwareProductComponentProcessesEditor.js';
+import SoftwareProductComponentsProcessesConfirmationModal from './SoftwareProductComponentsProcessesConfirmationModal.jsx';
+
+class SoftwareProductProcessesView extends React.Component {
+
+	state = {
+		localFilter: ''
+	};
+
+	static propTypes = {
+		onAddProcess: React.PropTypes.func,
+		onEditProcessClick: React.PropTypes.func,
+		onDeleteProcessClick: React.PropTypes.func,
+		isDisplayModal: React.PropTypes.bool,
+		isModalInEditMode: React.PropTypes.bool,
+		onStorageSelect: React.PropTypes.func,
+		componentId: React.PropTypes.string,
+		softwareProductId: React.PropTypes.string
+	};
+
+	render() {
+		let { softwareProductId, componentId} = this.props;
+
+		return (
+			<div className='vsp-processes-page'>
+				<div className='software-product-view'>
+					<div className='software-product-landing-view-right-side flex-column'>
+						{this.renderEditor()}
+						{this.renderProcessList()}
+					</div>
+					<SoftwareProductComponentsProcessesConfirmationModal
+						componentId={componentId}
+						softwareProductId={softwareProductId}/>
+				</div>
+			</div>
+		);
+	}
+
+	renderEditor() {
+		let {softwareProductId, componentId, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
+		return (
+			<Modal show={isDisplayModal} bsSize='large' animation={true}>
+				<Modal.Header>
+					<Modal.Title>{isModalInEditMode ? i18n('Edit Process Details') : i18n('Create New Process Details')}</Modal.Title>
+				</Modal.Header>
+				<Modal.Body className='edit-process-modal'>
+					<SoftwareProductProcessesEditor
+						componentId={componentId}
+						softwareProductId={softwareProductId}
+						isReadOnlyMode={isReadOnlyMode}/>
+				</Modal.Body>
+			</Modal>
+
+		);
+	}
+
+	renderProcessList() {
+		const {localFilter} = this.state;
+		let {onAddProcess, isReadOnlyMode} = this.props;
+		return (
+			<div className='processes-list'>
+				<ListEditorView
+					plusButtonTitle={i18n('Add Component Process Details')}
+					filterValue={localFilter}
+					placeholder={i18n('Filter Process')}
+					onAdd={onAddProcess}
+					isReadOnlyMode={isReadOnlyMode}
+					onFilter={filter => this.setState({localFilter: filter})}>
+					{this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))}
+				</ListEditorView>
+			</div>
+		);
+	}
+
+	renderProcessListItem(process, isReadOnlyMode) {
+		let {id, name, description, artifactName = ''} = process;
+		let {onEditProcessClick, onDeleteProcessClick} =  this.props;
+		return (
+			<ListEditorItemView
+				key={id}
+				className='list-editor-item-view'
+				isReadOnlyMode={isReadOnlyMode}
+				onSelect={() => onEditProcessClick(process)}
+				onDelete={() => onDeleteProcessClick(process)}>
+
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Name')}</div>
+					<div className='name'>{name}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Artifact name')}</div>
+					<div className='artifact-name'>{artifactName}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Notes')}</div>
+					<div className='description'>{description}</div>
+				</div>
+			</ListEditorItemView>
+		);
+	}
+
+
+	filterList() {
+		let {processesList} = this.props;
+		let {localFilter} = this.state;
+		if (localFilter.trim()) {
+			const filter = new RegExp(escape(localFilter), 'i');
+			return processesList.filter(({name = '', description = ''}) => {
+				return escape(name).match(filter) || escape(description).match(filter);
+			});
+		}
+		else {
+			return processesList;
+		}
+	}
+}
+
+export default SoftwareProductProcessesView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js
new file mode 100644
index 0000000..fbd3f81
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
+import SoftwareProductComponentStorageView from './SoftwareProductComponentStorageView.jsx';
+
+const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
+	let {componentEditor: {data: componentData , qdata, qschema}} = softwareProductComponents;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+
+	return {
+		componentData,
+		qdata,
+		qschema,
+		isReadOnlyMode
+	};
+};
+
+const mapActionToProps = (dispatch, {softwareProductId, componentId}) => {
+	return {
+		onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+		onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});}
+	};
+};
+
+export default connect(mapStateToProps, mapActionToProps, null, {withRef: true}) (SoftwareProductComponentStorageView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx
new file mode 100644
index 0000000..9c9600c
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx
@@ -0,0 +1,124 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+
+
+class SoftwareProductComponentStorageView extends React.Component {
+
+	static propTypes = {
+		componentId: React.PropTypes.string,
+		onQDataChanged: React.PropTypes.func,
+		onSubmit: React.PropTypes.func,
+		isReadOnlyMode: React.PropTypes.bool
+	};
+
+	render() {
+		let {qdata, qschema, onQDataChanged, onSubmit, isReadOnlyMode} = this.props;
+
+		return(
+			<div className='vsp-component-questionnaire-view'>
+				<ValidationForm
+					ref='storageValidationForm'
+					hasButtons={false}
+					onSubmit={() => onSubmit({qdata})}
+					className='component-questionnaire-validation-form'
+					isReadOnlyMode={isReadOnlyMode}
+					onDataChanged={onQDataChanged}
+					data={qdata}
+					schema={qschema}>
+
+					<div className='section-title'>{i18n('Backup')}</div>
+					<div className='rows-section'>
+						<div className='row-flex-components input-row'>
+							<div className='single-col'>
+								<div className='vertical-flex'>
+									<label key='label' className='control-label'>{i18n('Backup Type')}</label>
+									<div className='radio-options-content-row'>
+										<ValidationInput
+											label={i18n('On Site')}
+											type='radiogroup'
+											pointer={'/storage/backup/backupType'}
+											className='radio-field'/>
+									</div>
+								</div>
+							</div>
+							<div className='single-col'>
+								<ValidationInput
+									type='text'
+									label={i18n('Backup Solution')}
+									pointer={'/storage/backup/backupSolution'}
+									className='section-field'/>
+							</div>
+							<div className='single-col'>
+								<ValidationInput
+									type='text'
+									label={i18n('Backup Storage Size (GB)')}
+									pointer={'/storage/backup/backupStorageSize'}
+									className='section-field'/>
+							</div>
+							<ValidationInput
+								type='select'
+								label={i18n('Backup NIC')}
+								pointer={'/storage/backup/backupNIC'}
+								className='section-field'/>
+						</div>
+					</div>
+
+					<div className='section-title'>{i18n('Snapshot Backup')}</div>
+					<div className='rows-section'>
+						<div className='row-flex-components input-row'>
+							<div className='single-col'>
+								<ValidationInput
+									type='text'
+									label={i18n('Snapshot Frequency (hours)')}
+									pointer={'/storage/snapshotBackup/snapshotFrequency'}
+									className='section-field'/>
+							</div>
+							<div className='empty-two-col' />
+							<div className='empty-col' />
+						</div>
+					</div>
+
+					<div className='section-title'>{i18n('Log Backup')}</div>
+					<div className='rows-section'>
+						<div className='row-flex-components input-row'>
+							<div className='single-col'>
+								<ValidationInput
+									type='text'
+									label={i18n('Size of Log Files (GB)')}
+									pointer={'/storage/logBackup/sizeOfLogFiles'}
+									className='section-field'/>
+								</div>
+							<div className='single-col'>
+							<ValidationInput
+								type='text'
+								label={i18n('Log Retention Period (days)')}
+								pointer={'/storage/logBackup/logRetentionPeriod'}
+								className='section-field'/>
+								</div>
+							<div className='single-col'>
+							<ValidationInput
+								type='text'
+								label={i18n('Log Backup Frequency (days)')}
+								pointer={'/storage/logBackup/logBackupFrequency'}
+								className='section-field'/>
+							</div>
+							<ValidationInput
+								type='text'
+								label={i18n('Log File Location')}
+								pointer={'/storage/logBackup/logFileLocation'}
+								className='section-field'/>
+						</div>
+					</div>
+				</ValidationForm>
+			</div>
+		);
+	}
+
+	save(){
+		return this.refs.storageValidationForm.handleFormSubmit(new Event('dummy'));
+	}
+}
+
+export default SoftwareProductComponentStorageView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js
new file mode 100644
index 0000000..46308f0
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+import SoftwareProductCreationActionHelper from './SoftwareProductCreationActionHelper.js';
+import SoftwareProductCreationView from './SoftwareProductCreationView.jsx';
+
+const mapStateToProps = ({finalizedLicenseModelList, softwareProduct: {softwareProductCreation, softwareProductCategories} }) => {
+	return {
+		data: softwareProductCreation.data,
+		softwareProductCategories,
+		finalizedLicenseModelList
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onDataChanged: deltaData => SoftwareProductCreationActionHelper.changeData(dispatch, {deltaData}),
+		onCancel: () => SoftwareProductCreationActionHelper.resetData(dispatch),
+		onSubmit: (softwareProduct) => {
+			SoftwareProductCreationActionHelper.resetData(dispatch);
+			SoftwareProductCreationActionHelper.createSoftwareProduct(dispatch, {softwareProduct}).then(softwareProductId => {
+				let {vendorId: licenseModelId, licensingVersion} = softwareProduct;
+				OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, licensingVersion});
+			});
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductCreationView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js
new file mode 100644
index 0000000..f4e51f1
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+
+import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
+import {actionTypes} from './SoftwareProductCreationConstants.js';
+
+
+function baseUrl() {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-software-products/`;
+}
+
+function createSoftwareProduct(softwareProduct) {
+	return RestAPIUtil.create(baseUrl(), {
+		...softwareProduct,
+		icon: 'icon',
+		licensingData: {}
+	});
+}
+
+const SoftwareProductCreationActionHelper = {
+
+	open(dispatch) {
+		SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch);
+		dispatch({
+			type: actionTypes.OPEN
+		});
+	},
+
+	resetData(dispatch) {
+		dispatch({
+			type: actionTypes.RESET_DATA
+		});
+	},
+
+	changeData(dispatch, {deltaData}) {
+		dispatch({
+			type: actionTypes.DATA_CHANGED,
+			deltaData
+		});
+	},
+
+	createSoftwareProduct(dispatch, {softwareProduct}) {
+		return createSoftwareProduct(softwareProduct).then(response => {
+			SoftwareProductActionHelper.addSoftwareProduct(dispatch, {
+				softwareProduct: {
+					...softwareProduct,
+					id: response.vspId
+				}
+			});
+			return response.vspId;
+		});
+	}
+
+};
+
+export default SoftwareProductCreationActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js
new file mode 100644
index 0000000..0a9cdb9
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	OPEN: null,
+	RESET_DATA: null,
+	DATA_CHANGED: null
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
new file mode 100644
index 0000000..5e3db09
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductCreationConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.OPEN:
+			return {
+				...state,
+				data: {},
+				showModal: true
+			};
+		case actionTypes.DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		case actionTypes.RESET_DATA:
+			return {};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx
new file mode 100644
index 0000000..2c8f243
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx
@@ -0,0 +1,123 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+
+import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
+
+
+const SoftwareProductPropType = React.PropTypes.shape({
+	id: React.PropTypes.string,
+	name: React.PropTypes.string,
+	description: React.PropTypes.string,
+	category: React.PropTypes.string,
+	subCategory: React.PropTypes.string,
+	vendorId: React.PropTypes.string
+});
+
+class SoftwareProductCreationView extends React.Component {
+
+	static propTypes = {
+		data: SoftwareProductPropType,
+		finalizedLicenseModelList: React.PropTypes.array,
+		softwareProductCategories: React.PropTypes.array,
+		onDataChanged: React.PropTypes.func.isRequired,
+		onSubmit: React.PropTypes.func.isRequired,
+		onCancel: React.PropTypes.func.isRequired
+	};
+
+	render() {
+		let {softwareProductCategories, data = {}, onDataChanged, onCancel} = this.props;
+		let {name, description, vendorId, subCategory} = data;
+
+		const vendorList = this.getVendorList();
+
+		return (
+			<div className='software-product-creation-page'>
+				<ValidationForm
+					ref='validationForm'
+					hasButtons={true}
+					onSubmit={() => this.submit() }
+					onReset={() => onCancel() }
+					labledButtons={true}>
+					<div className='software-product-form-row'>
+						<div className='software-product-inline-section'>
+							<ValidationInput
+								value={name}
+								label={i18n('Name')}
+								ref='software-product-name'
+								onChange={name => onDataChanged({name})}
+								validations={{validateName: true, maxLength: 25, required: true}}
+								type='text'
+								className='field-section'/>
+							<ValidationInput
+								onEnumChange={vendorId => onDataChanged({vendorId})}
+								value={vendorId}
+								label={i18n('Vendor')}
+								values={vendorList}
+								validations={{required: true}}
+								type='select'
+								className='field-section'/>
+							<ValidationInput
+								label={i18n('Category')}
+								type='select'
+								value={subCategory}
+								onChange={subCategory => this.onSelectSubCategory(subCategory)}
+								validations={{required: true}}
+								className='options-input-category'>
+								<option key='' value=''>{i18n('please select…')}</option>
+								{softwareProductCategories.map(category =>
+									category.subcategories &&
+									<optgroup
+										key={category.name}
+										label={category.name}>{category.subcategories.map(sub =>
+										<option key={sub.uniqueId} value={sub.uniqueId}>{`${sub.name} (${category.name})`}</option>)}
+									</optgroup>)
+								}
+							</ValidationInput>
+						</div>
+						<div className='software-product-inline-section'>
+							<ValidationInput
+								value={description}
+								label={i18n('Description')}
+								ref='description'
+								onChange={description => onDataChanged({description})}
+								validations={{freeEnglishText: true, maxLength: 1000, required: true}}
+								type='textarea'
+								className='field-section'/>
+						</div>
+					</div>
+				</ValidationForm>
+			</div>
+		);
+	}
+
+	getVendorList() {
+		let {finalizedLicenseModelList} =  this.props;
+
+		return [{enum: '', title: i18n('please select...')}].concat(finalizedLicenseModelList.map(vendor => {
+			return {
+				enum: vendor.id,
+				title: vendor.vendorName
+			};
+		}));
+	}
+
+	onSelectSubCategory(subCategory) {
+		let {softwareProductCategories, onDataChanged} = this.props;
+		let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories);
+		onDataChanged({category, subCategory});
+	}
+
+	create(){
+		this.refs.validationForm.handleFormSubmit(new Event('dummy'));
+	}
+
+	submit() {
+		const {data:softwareProduct, finalizedLicenseModelList} = this.props;
+		softwareProduct.vendorName = finalizedLicenseModelList.find(vendor => vendor.id === softwareProduct.vendorId).vendorName;
+		this.props.onSubmit(softwareProduct);
+	}
+}
+
+export default SoftwareProductCreationView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js
new file mode 100644
index 0000000..16a100c
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
+import SoftwareProductDetailsView from './SoftwareProductDetailsView.jsx';
+
+export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, licenseModel: {licenseAgreement, featureGroup}}) => {
+	let {softwareProductEditor: {data: currentSoftwareProduct}, softwareProductCategories, softwareProductQuestionnaire} = softwareProduct;
+	let {licensingData = {}, licensingVersion} = currentSoftwareProduct;
+	let licenseAgreementList = [], filteredFeatureGroupsList = [];
+	if(licensingVersion && licensingVersion !== '') {
+		licenseAgreementList = licenseAgreement.licenseAgreementList;
+		let selectedLicenseAgreement = licenseAgreementList.find(la => la.id === licensingData.licenseAgreement);
+		if (selectedLicenseAgreement) {
+			let featureGroupsList = featureGroup.featureGroupsList.filter(({referencingLicenseAgreements}) => referencingLicenseAgreements.includes(selectedLicenseAgreement.id));
+			if (featureGroupsList.length) {
+				filteredFeatureGroupsList = featureGroupsList.map(featureGroup => ({enum: featureGroup.id, title: featureGroup.name}));
+			}
+		}
+	}
+	let {qdata, qschema} = softwareProductQuestionnaire;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+
+	return {
+		currentSoftwareProduct,
+		softwareProductCategories,
+		licenseAgreementList,
+		featureGroupsList: filteredFeatureGroupsList,
+		finalizedLicenseModelList,
+		qdata,
+		qschema,
+		isReadOnlyMode
+	};
+};
+
+export const mapActionsToProps = (dispatch) => {
+	return {
+		onDataChanged: deltaData => SoftwareProductActionHelper.softwareProductEditorDataChanged(dispatch, {deltaData}),
+		onVendorParamChanged: deltaData => SoftwareProductActionHelper.softwareProductEditorVendorChanged(dispatch, {deltaData}),
+		onQDataChanged: ({data}) => SoftwareProductActionHelper.softwareProductQuestionnaireUpdate(dispatch, {data}),
+		onValidityChanged: isValidityData => SoftwareProductActionHelper.setIsValidityData(dispatch, {isValidityData}),
+		onSubmit: (softwareProduct, qdata) =>{ return SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductDetailsView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js
new file mode 100644
index 0000000..e060706
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.softwareProductEditor.OPEN:
+			return {
+				...state,
+				data: {}
+			};
+		case actionTypes.softwareProductEditor.DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		case actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION:
+			return {
+				...state,
+				uploadData:action.uploadData
+			};
+		case actionTypes.softwareProductEditor.IS_VALIDITY_DATA_CHANGED:
+			return {
+				...state,
+				isValidityData: action.isValidityData
+			};
+		case actionTypes.softwareProductEditor.CLOSE:
+			return {};
+		case actionTypes.SOFTWARE_PRODUCT_LOADED:
+			return {
+				...state,
+				data: action.response
+			};
+		case actionTypes.TOGGLE_NAVIGATION_ITEM:
+			return {
+				...state,
+				mapOfExpandedIds: action.mapOfExpandedIds
+			};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx
new file mode 100644
index 0000000..75a5797
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx
@@ -0,0 +1,264 @@
+import React, {Component, PropTypes} from 'react';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Form from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
+
+class SoftwareProductDetails extends Component {
+
+	static propTypes = {
+		vendorName: PropTypes.string,
+		currentSoftwareProduct: PropTypes.shape({
+			id: PropTypes.string,
+			name: PropTypes.string,
+			description: PropTypes.string,
+			category: PropTypes.string,
+			subCategory: PropTypes.string,
+			vendorId: PropTypes.string,
+			vendorName: PropTypes.string,
+			licensingVersion: PropTypes.string,
+			licensingData: PropTypes.shape({
+				licenceAgreement: PropTypes.string,
+				featureGroups: PropTypes.array
+			})
+		}),
+		softwareProductCategories: PropTypes.array,
+		finalizedLicenseModelList: PropTypes.array,
+		licenseAgreementList: PropTypes.array,
+		featureGroupsList: PropTypes.array,
+		onSubmit: PropTypes.func.isRequired,
+		onDataChanged: PropTypes.func.isRequired,
+		onValidityChanged: PropTypes.func.isRequired,
+		qdata: PropTypes.object.isRequired,
+		qschema: PropTypes.object.isRequired,
+		onQDataChanged: PropTypes.func.isRequired,
+		onVendorParamChanged: PropTypes.func.isRequired
+	};
+
+	state = {
+		licensingVersionsList: []
+	};
+
+	render() {
+		let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, featureGroupsList, licenseAgreementList, currentSoftwareProduct} = this.props;
+		let {name, description, vendorId, licensingVersion, subCategory, licensingData = {}} = currentSoftwareProduct;
+		let licensingVersionsList = this.state.licensingVersionsList.length > 0 ? this.state.licensingVersionsList : this.refreshVendorVersionsList(vendorId);
+		let {qdata, qschema, onQDataChanged} = this.props;
+		let {isReadOnlyMode} = this.props;
+
+		return (
+			<div className='vsp-details-page'>
+				<Form
+					ref='validationForm'
+					className='vsp-general-tab'
+					hasButtons={false}
+					onSubmit={() => this.props.onSubmit(currentSoftwareProduct, qdata)}
+					onValidityChanged={(isValidityData) => this.props.onValidityChanged(isValidityData)}
+					isReadOnlyMode={isReadOnlyMode}>
+					<div className='section-title general'>{i18n('General')}</div>
+					<div className='vsp-general-tab-inline-section'>
+						<div className='vsp-general-tab-sub-section'>
+							<ValidationInput
+								label={i18n('Name')}
+								type='text'
+								value={name}
+								onChange={name => onDataChanged({name})}
+								validations={{validateName: true, maxLength: 120, required: true}}
+								className='field-section'/>
+							<ValidationInput
+								label={i18n('Vendor')}
+								type='select'
+								selectedEnum={vendorId}
+								onEnumChange={vendorId => this.onVendorParamChanged({vendorId})}
+								className='field-section'>
+								{finalizedLicenseModelList.map(lm => <option key={lm.id} value={lm.id}>{lm.vendorName}</option>)}
+							</ValidationInput>
+							<div className='input-row'>
+								<ValidationInput
+									label={i18n('Category')}
+									type='select'
+									selectedEnum={subCategory}
+									onEnumChange={subCategory => this.onSelectSubCategory(subCategory)}
+									className='field-section'>
+									{
+										softwareProductCategories.map(category =>
+											category.subcategories &&
+											<optgroup
+												key={category.name}
+												label={category.name}>{category.subcategories.map(sub =>
+												<option
+													key={sub.uniqueId}
+													value={sub.uniqueId}>{`${sub.name} (${category.name})`}</option>)}
+											</optgroup>
+										)
+									}
+								</ValidationInput>
+							</div>
+						</div>
+						<div className='vsp-general-tab-sub-section input-row'>
+							<ValidationInput
+								label={i18n('Description')}
+								type='textarea'
+								value={description}
+								onChange={description => onDataChanged({description})}
+								className='field-section'
+								validations={{required: true}}/>
+						</div>
+					</div>
+					<div className='vsp-general-tab-section licenses'>
+						<div className='section-title'>{i18n('Licenses')}</div>
+						<div className='vsp-general-tab-inline-section input-row'>
+							<ValidationInput
+								onEnumChange={licensingVersion => this.onVendorParamChanged({vendorId, licensingVersion})}
+								selectedEnum={licensingVersion}
+								label={i18n('Licensing Version')}
+								values={licensingVersionsList}
+								type='select'
+								className='field-section'/>
+							<ValidationInput
+								label={i18n('License Agreement')}
+								type='select'
+								selectedEnum={licensingData.licenseAgreement}
+								className='field-section'
+								onEnumChange={(licenseAgreement) => this.onLicensingDataChanged({licenseAgreement, featureGroups: []})}>
+								<option key='placeholder' value=''>{i18n('Select...')}</option>
+								{licenseAgreementList.map(la => <option value={la.id} key={la.id}>{la.name}</option>)}
+							</ValidationInput>
+						</div>
+						<div className='vsp-general-tab-inline-section input-row'>
+							{licensingData.licenseAgreement && (
+								<ValidationInput
+									type='select'
+									isMultiSelect={true}
+									onEnumChange={featureGroups => this.onFeatureGroupsChanged({featureGroups})}
+									multiSelectedEnum={licensingData.featureGroups}
+									name='feature-groups'
+									label={i18n('Feature Groups')}
+									clearable={false}
+									values={featureGroupsList}/>)
+							}
+						</div>
+					</div>
+				</Form>
+				<Form
+					data={qdata}
+					schema={qschema}
+					onDataChanged={onQDataChanged}
+					className='vsp-general-tab'
+					hasButtons={false}
+					isReadOnlyMode={isReadOnlyMode}>
+					<div className='vsp-general-tab-section'>
+						<div className='section-title'> {i18n('Availability')} </div>
+						<div className='vsp-general-tab-inline-section'>
+							<div className='vsp-general-tab-sub-section input-row'>
+								<ValidationInput
+									label={i18n('Use Availability Zones for High Availability')}
+									type='checkbox'
+									pointer='/general/availability/useAvailabilityZonesForHighAvailability'/>
+							</div>
+						</div>
+						<div className='section-title'> {i18n('Regions')} </div>
+						<div className='vsp-general-tab-inline-section'>
+							<div className='vsp-general-tab-sub-section input-row'>
+								<ValidationInput
+									type='select'
+									laebl='Ziv'
+									pointer='/general/regionsData/regions'/>
+							</div>
+						</div>
+						<div className='section-title'> {i18n('Storage Data Replication')} </div>
+						<div className='vsp-general-tab-inline-section'>
+							<div className='vsp-general-tab-sub-section'>
+								<ValidationInput
+									label={i18n('Storage Replication Size (GB)')}
+									type='text'
+									pointer='/general/storageDataReplication/storageReplicationSize'
+									className='field-section'/>
+								<ValidationInput
+									label={i18n('Storage Replication Source')}
+									type='text'
+									pointer='/general/storageDataReplication/storageReplicationSource'
+									className='field-section'/>
+							</div>
+							<div className='vsp-general-tab-sub-section'>
+								<ValidationInput
+									label={i18n('Storage Replication Frequency (minutes)')}
+									type='text'
+									pointer='/general/storageDataReplication/storageReplicationFrequency'
+									className='field-section'/>
+								<ValidationInput
+									label={i18n('Storage Replication Destination')}
+									type='text'
+									pointer='/general/storageDataReplication/storageReplicationDestination'
+									className='field-section'/>
+							</div>
+						</div>
+					</div>
+				</Form>
+			</div>
+		);
+	}
+
+	onVendorParamChanged({vendorId, licensingVersion}) {
+		let {finalizedLicenseModelList, onVendorParamChanged} = this.props;
+		if(!licensingVersion) {
+			const licensingVersionsList = this.refreshVendorVersionsList(vendorId);
+			licensingVersion = licensingVersionsList.length > 0 ? licensingVersionsList[0].enum : '';
+		}
+		let vendorName = finalizedLicenseModelList.find(licenseModelItem => licenseModelItem.id === vendorId).vendorName || '';
+		let deltaData = {
+			vendorId,
+			vendorName,
+			licensingVersion,
+			licensingData: {}
+		};
+		onVendorParamChanged(deltaData);
+	}
+
+	refreshVendorVersionsList(vendorId) {
+		if(!vendorId) {
+			return [];
+		}
+
+		let {finalVersions} = this.props.finalizedLicenseModelList.find(vendor => vendor.id === vendorId);
+
+		let licensingVersionsList = [{
+			enum: '',
+			title: i18n('Select...')
+		}];
+		if(finalVersions) {
+			finalVersions.forEach(version => licensingVersionsList.push({
+				enum: version,
+				title: version
+			}));
+		}
+
+		return licensingVersionsList;
+	}
+
+	onSelectSubCategory(subCategory) {
+		let {softwareProductCategories, onDataChanged} = this.props;
+		let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories);
+		onDataChanged({category, subCategory});
+	}
+
+	onFeatureGroupsChanged({featureGroups}) {
+		this.onLicensingDataChanged({featureGroups});
+	}
+
+	onLicensingDataChanged(deltaData) {
+		this.props.onDataChanged({
+			licensingData: {
+				...this.props.currentSoftwareProduct.licensingData,
+				...deltaData
+			}
+		});
+	}
+
+	save(){
+		return this.refs.validationForm.handleFormSubmit(new Event('dummy'));
+	}
+}
+
+export default SoftwareProductDetails;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js
new file mode 100644
index 0000000..7604f58
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js
@@ -0,0 +1,97 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
+import LandingPageView from './SoftwareProductLandingPageView.jsx';
+
+const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) => {
+	let {softwareProductEditor: {data:currentSoftwareProduct = {}}, softwareProductComponents, softwareProductCategories = []} = softwareProduct;
+	let {licensingData = {}} = currentSoftwareProduct;
+	let {licenseAgreementList} = licenseAgreement;
+	let {componentsList} = softwareProductComponents;
+	let licenseAgreementName = licenseAgreementList.find(la => la.id === licensingData.licenseAgreement);
+	if (licenseAgreementName) {
+		licenseAgreementName = licenseAgreementName.name;
+	}
+
+	let categoryName = '', subCategoryName = '', fullCategoryDisplayName = '';
+	const category = softwareProductCategories.find(ca => ca.uniqueId === currentSoftwareProduct.category);
+	if (category) {
+		categoryName = category.name;
+		const subcategories = category.subcategories || [];
+		const subcat = subcategories.find(sc => sc.uniqueId === currentSoftwareProduct.subCategory);
+		subCategoryName = subcat && subcat.name ? subcat.name : '';
+	}
+	fullCategoryDisplayName = `${subCategoryName} (${categoryName})`;
+
+	const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+
+	return {
+		currentSoftwareProduct: {
+			...currentSoftwareProduct,
+			licenseAgreementName,
+			fullCategoryDisplayName
+		},
+		isReadOnlyMode,
+		componentsList
+	};
+};
+
+const mapActionsToProps = (dispatch, {version}) => {
+	return {
+		onDetailsSelect: ({id: softwareProductId, vendorId: licenseModelId}) => OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {
+			softwareProductId,
+			licenseModelId
+		}),
+		onAttachmentsSelect: ({id: softwareProductId}) => OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId}),
+		onUpload: (softwareProductId, formData) =>
+			SoftwareProductActionHelper.uploadFile(dispatch, {
+				softwareProductId,
+				formData,
+				failedNotificationTitle: i18n('Upload validation failed')
+			}),
+		onUploadConfirmation: (softwareProductId, formData) =>
+			SoftwareProductActionHelper.uploadConfirmation(dispatch, {
+				softwareProductId,
+				formData,
+				failedNotificationTitle: i18n('Upload validation failed')}),
+
+		onInvalidFileSizeUpload: () => dispatch({
+			type: NotificationConstants.NOTIFY_ERROR,
+			data: {
+				title: i18n('Upload Failed'),
+				msg: i18n('no zip file was uploaded or zip file doesn\'t exist')
+			}
+		}),
+		onComponentSelect: ({id: softwareProductId, componentId}) => {
+			OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version });
+		},
+		/** for the next version */
+		onAddComponent: () => SoftwareProductActionHelper.addComponent(dispatch)
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(LandingPageView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx
new file mode 100644
index 0000000..4a84883
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx
@@ -0,0 +1,38 @@
+import {connect} from 'react-redux';
+import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
+import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductEditor} = softwareProduct;
+	let {uploadData} = softwareProductEditor;
+	const show = uploadData ? true : false;
+	return {
+		show,
+		title: 'Warning!',
+		type: 'warning',
+		msg: i18n('Upload will erase existing data. Do you want to continue?'),
+		confirmationDetails: {uploadData}
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onConfirmed: ({uploadData}) => {
+			let {softwareProductId, formData, failedNotificationTitle} = uploadData;
+			SoftwareProductActionHelper.uploadFile(dispatch, {
+				softwareProductId,
+				formData,
+				failedNotificationTitle
+			});
+			SoftwareProductActionHelper.hideUploadConfirm(dispatch);
+		},
+		onDeclined: () => {
+			SoftwareProductActionHelper.hideUploadConfirm(dispatch);
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx
new file mode 100644
index 0000000..cf7c7a3
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx
@@ -0,0 +1,272 @@
+import React from 'react';
+import classnames from 'classnames';
+import Dropzone from 'react-dropzone';
+
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+
+import FontAwesome from 'react-fontawesome';
+import SoftwareProductLandingPageUploadConfirmationModal from './SoftwareProductLandingPageUploadConfirmationModal.jsx';
+
+
+const SoftwareProductPropType = React.PropTypes.shape({
+	name: React.PropTypes.string,
+	description: React.PropTypes.string,
+	version: React.PropTypes.string,
+	id: React.PropTypes.string,
+	categoryId: React.PropTypes.string,
+	vendorId: React.PropTypes.string,
+	status: React.PropTypes.string,
+	licensingData: React.PropTypes.object,
+	validationData: React.PropTypes.object
+});
+
+const ComponentPropType = React.PropTypes.shape({
+	id: React.PropTypes.string,
+	name: React.PropTypes.string,
+	displayName: React.PropTypes.string,
+	description: React.PropTypes.string
+});
+
+class SoftwareProductLandingPageView extends React.Component {
+
+	state = {
+		localFilter: '',
+		fileName: '',
+		dragging: false,
+		files: []
+	};
+
+	static propTypes = {
+		currentSoftwareProduct: SoftwareProductPropType,
+		isReadOnlyMode: React.PropTypes.bool,
+		componentsList: React.PropTypes.arrayOf(ComponentPropType),
+		onDetailsSelect: React.PropTypes.func,
+		onAttachmentsSelect: React.PropTypes.func,
+		onUpload: React.PropTypes.func,
+		onUploadConfirmation: React.PropTypes.func,
+		onInvalidFileSizeUpload: React.PropTypes.func,
+		onComponentSelect: React.PropTypes.func,
+		onAddComponent: React.PropTypes.func
+	};
+
+	render() {
+		let {currentSoftwareProduct, isReadOnlyMode, componentsList = []} =  this.props;
+		return (
+			<div className='software-product-landing-wrapper'>
+				<Dropzone
+					className={classnames('software-product-landing-view', {'active-dragging': this.state.dragging})}
+					onDrop={files => this.handleImportSubmit(files, isReadOnlyMode)}
+					onDragEnter={() => this.handleOnDragEnter(isReadOnlyMode)}
+					onDragLeave={() => this.setState({dragging:false})}
+					multiple={false}
+					disableClick={true}
+					ref='fileInput'
+					name='fileInput'
+					accept='.zip'
+					disabled>
+					<div className='draggable-wrapper'>
+						<div className='software-product-landing-view-top'>
+							<div className='row'>
+								{this.renderProductSummary(currentSoftwareProduct)}
+								{this.renderProductDetails(currentSoftwareProduct, isReadOnlyMode)}
+							</div>
+						</div>
+					</div>
+				</Dropzone>
+				{
+					componentsList.length > 0 && this.renderComponents()
+				}
+				<SoftwareProductLandingPageUploadConfirmationModal confirmationButtonText={i18n('Continue')}/>
+			</div>
+		);
+	}
+
+	handleOnDragEnter(isReadOnlyMode) {
+		if (!isReadOnlyMode) {
+			this.setState({dragging: true});
+		}
+	}
+
+	renderProductSummary(currentSoftwareProduct) {
+		let {name = '', description = '', vendorName = '', fullCategoryDisplayName = '', licenseAgreementName = ''}  = currentSoftwareProduct;
+		let {onDetailsSelect} = this.props;
+		return (
+			<div className='details-panel'>
+				<div className='software-product-landing-view-heading-title'>{i18n('Software Product Details')}</div>
+				<div
+					className='software-product-landing-view-top-block clickable'
+					onClick={() => onDetailsSelect(currentSoftwareProduct)}>
+					<div className='details-container'>
+						<div className='single-detail-section title-section'>
+							<div>
+								<div>{name}</div>
+							</div>
+						</div>
+						<div className='multiple-details-section'>
+							<div className='detail-col' >
+								<div className='title'>{i18n('Vendor')}</div>
+								<div className='description'>{vendorName}</div>
+							</div>
+							<div className='detail-col'>
+								<div className='title'>{i18n('Category')}</div>
+								<div className='description'>{fullCategoryDisplayName}</div>
+							</div>
+							<div className='detail-col'>
+								<div className='title extra-large'>{i18n('License Agreement')}</div>
+								<div className='description'>
+									{this.renderLicenseAgreement(licenseAgreementName)}
+								</div>
+							</div>
+						</div>
+						<div className='single-detail-section'>
+							<div className='title'>{i18n('Description')}</div>
+							<div className='description'>{description}</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		);
+	}
+
+	renderProductDetails(currentSoftwareProduct, isReadOnlyMode) {
+		let {validationData} = currentSoftwareProduct;
+		let {onAttachmentsSelect} = this.props;
+		let details = {
+			heatTemplates: validationData ? '1' : '0',
+			images: '0',
+			otherArtifacts: '0'
+		};
+
+		return (
+			<div className='details-panel'>
+				<div className='software-product-landing-view-heading-title'>{i18n('Software Product Attachments')}</div>
+				<div className='software-product-landing-view-top-block'>
+					<div
+						className='software-product-landing-view-top-block-col'
+						onClick={() => onAttachmentsSelect(currentSoftwareProduct)}>
+						<div>
+							<div className='attachment-details'>{i18n('HEAT Templates')} (<span
+								className='attachment-details-count'>{details.heatTemplates}</span>)
+							</div>
+							<div className='attachment-details'>{i18n('Images')} (<span
+								className='attachment-details-count'>{details.images}</span>)
+							</div>
+							<div className='attachment-details'>{i18n('Other Artifacts')} (<span
+								className='attachment-details-count'>{details.otherArtifacts}</span>)
+							</div>
+						</div>
+					</div>
+					<div
+						className={classnames('software-product-landing-view-top-block-col-upl', {'disabled': isReadOnlyMode})}>
+						<div className='drag-text'>{i18n('Drag & drop for upload')}</div>
+						<div className='or-text'>{i18n('or')}</div>
+						<div className='upload-btn primary-btn' onClick={() => this.refs.fileInput.open()}>
+							<span className='primary-btn-text'>{i18n('Select file')}</span>
+						</div>
+					</div>
+				</div>
+			</div>
+		);
+	}
+
+	renderComponents() {
+		const {localFilter} = this.state;
+
+		return (
+			<ListEditorView
+				title={i18n('Virtual Function Components')}
+				filterValue={localFilter}
+				placeholder={i18n('Filter Components')}
+				onFilter={filter => this.setState({localFilter: filter})}>
+				{this.filterList().map(component => this.renderComponentsListItem(component))}
+			</ListEditorView>
+		);
+	}
+
+	renderComponentsListItem(component) {
+		let {id: componentId, name, displayName, description = ''} = component;
+		let {currentSoftwareProduct: {id}, onComponentSelect} = this.props;
+		return (
+			<ListEditorItemView
+				key={name + Math.floor(Math.random() * (100 - 1) + 1).toString()}
+				className='list-editor-item-view'
+				onSelect={() => onComponentSelect({id, componentId})}>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Component')}</div>
+					<div className='name'>{displayName}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Description')}</div>
+					<div className='description'>{description}</div>
+				</div>
+			</ListEditorItemView>
+		);
+	}
+
+	renderLicenseAgreement(licenseAgreementName) {
+		if (!licenseAgreementName) {
+			return (<FontAwesome name='exclamation-triangle' className='warning-icon'/>);
+		}
+		return (licenseAgreementName);
+	}
+
+
+	filterList() {
+		let {componentsList = []} = this.props;
+
+		let {localFilter} = this.state;
+		if (localFilter.trim()) {
+			const filter = new RegExp(escape(localFilter), 'i');
+			return componentsList.filter(({displayName = '', description = ''}) => {
+				return escape(displayName).match(filter) || escape(description).match(filter);
+			});
+		}
+		else {
+			return componentsList;
+		}
+	}
+
+	handleImportSubmit(files, isReadOnlyMode) {
+		if (isReadOnlyMode) {
+			return;
+		}
+		if (files[0] && files[0].size) {
+			this.setState({
+				fileName: files[0].name,
+				dragging: false,
+				complete: '0',
+			});
+			this.startUploading(files);
+		}
+		else {
+			this.props.onInvalidFileSizeUpload();
+		}
+
+	}
+
+	startUploading(files) {
+		let {onUpload, currentSoftwareProduct, onUploadConfirmation} = this.props;
+
+		let {validationData} = currentSoftwareProduct;
+
+		if (!(files && files.length)) {
+			return;
+		}
+		let file = files[0];
+		let formData = new FormData();
+		formData.append('upload', file);
+		this.refs.fileInput.value = '';
+
+		if (validationData) {
+			onUploadConfirmation(currentSoftwareProduct.id, formData);
+		}else {
+			onUpload(currentSoftwareProduct.id, formData);
+		}
+
+	}
+}
+
+export default SoftwareProductLandingPageView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js
new file mode 100644
index 0000000..dadc777
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductNetworksView from './SoftwareProductNetworksView.jsx';
+
+export const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductNetworks: {networksList = []}} = softwareProduct;
+	return {networksList};
+};
+
+export default connect(mapStateToProps, null, null, {withRef: true})(SoftwareProductNetworksView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js
new file mode 100644
index 0000000..d0e29bc
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductNetworksConstants.js';
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+
+function baseUrl(svpId) {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-software-products/${svpId}/networks`;
+}
+
+
+function fetchNetworksList(softwareProductId, version) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}${versionQuery}`);
+}
+
+const SoftwareProductNetworksActionHelper = {
+	fetchNetworksList(dispatch, {softwareProductId, version}) {
+		return fetchNetworksList(softwareProductId, version).then(response => {
+			dispatch({
+				type: actionTypes.FETCH_SOFTWARE_PRODUCT_NETWORKS,
+				networksList: response.results
+			});
+		});
+	}
+};
+
+export  default SoftwareProductNetworksActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js
new file mode 100644
index 0000000..d428d21
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js
@@ -0,0 +1,25 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	FETCH_SOFTWARE_PRODUCT_NETWORKS: null,
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js
new file mode 100644
index 0000000..0c9c623
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductNetworksConstants.js';
+
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.FETCH_SOFTWARE_PRODUCT_NETWORKS:
+			return [...action.networksList];
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx
new file mode 100644
index 0000000..bd47467
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx
@@ -0,0 +1,73 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+
+class SoftwareProductNetworksView extends React.Component {
+
+	static propTypes = {
+		networksList: React.PropTypes.arrayOf(React.PropTypes.shape({
+			id: React.PropTypes.string.isRequired,
+			name: React.PropTypes.string.isRequired,
+			dhcp: React.PropTypes.bool.isRequired
+		})).isRequired
+	};
+
+	state = {
+		localFilter: ''
+	};
+
+	render() {
+		const {localFilter} = this.state;
+
+		return (
+			<div className='vsp-networks-page'>
+				<ListEditorView
+					title={i18n('Networks')}
+					filterValue={localFilter}
+					placeholder={i18n('Filter Networks')}
+					onFilter={filter => this.setState({localFilter: filter})}>
+					{this.filterList().map(network => this.renderNetworksListItem(network))}
+				</ListEditorView>
+			</div>
+		);
+	}
+
+	renderNetworksListItem(network) {
+		let {id, name, dhcp} = network;
+		return (
+			<ListEditorItemView
+				key={id}
+				className='list-editor-item-view'
+				isReadOnlyMode={true}>
+
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Name')}</div>
+					<div className='name'>{name}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('DHCP')}</div>
+					<div className='artifact-name'>{dhcp ? i18n('YES') : i18n('NO')}</div>
+				</div>
+			</ListEditorItemView>
+		);
+	}
+
+	filterList() {
+		let {networksList} = this.props;
+
+		let {localFilter} = this.state;
+		if (localFilter.trim()) {
+			const filter = new RegExp(escape(localFilter), 'i');
+			return networksList.filter(({name = ''}) => {
+				return escape(name).match(filter);
+			});
+		}
+		else {
+			return networksList;
+		}
+	}
+}
+
+export default SoftwareProductNetworksView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js
new file mode 100644
index 0000000..5c3a8da
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+import SoftwareProductProcessesActionHelper from './SoftwareProductProcessesActionHelper.js';
+import SoftwareProductProcessesView from './SoftwareProductProcessesView.jsx';
+
+const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductEditor: {data: currentSoftwareProduct = {}}, softwareProductProcesses: {processesList, processesEditor}} = softwareProduct;
+	let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+	let {data} = processesEditor;
+
+	return {
+		currentSoftwareProduct,
+		processesList,
+		isDisplayEditor: Boolean(data),
+		isModalInEditMode: Boolean(data && data.id),
+		isReadOnlyMode
+	};
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId}) => {
+	return {
+		onAddProcess: () => SoftwareProductProcessesActionHelper.openEditor(dispatch),
+		onEditProcess: (process) => SoftwareProductProcessesActionHelper.openEditor(dispatch, process),
+		onDeleteProcess: (process) => SoftwareProductProcessesActionHelper.openDeleteProcessesConfirm(dispatch, {process, softwareProductId})
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductProcessesView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js
new file mode 100644
index 0000000..df5d08f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js
@@ -0,0 +1,151 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductProcessesConstants.js';
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+
+function baseUrl(svpId) {
+	const restPrefix = Configuration.get('restPrefix');
+	return `${restPrefix}/v1.0/vendor-software-products/${svpId}/processes`;
+}
+
+function putProcess(softwareProductId, process) {
+	return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${process.id}`, {
+		name: process.name,
+		description: process.description
+	});
+}
+
+function postProcess(softwareProductId, process) {
+	return RestAPIUtil.create(`${baseUrl(softwareProductId)}`, {
+		name: process.name,
+		description: process.description
+	});
+}
+
+function deleteProcess(softwareProductId, processId) {
+	return RestAPIUtil.destroy(`${baseUrl(softwareProductId)}/${processId}`);
+}
+
+function uploadFileToProcess(softwareProductId, processId, formData)
+{
+	return RestAPIUtil.create(`${baseUrl(softwareProductId)}/${processId}/upload`, formData);
+}
+
+function fetchProcesses(softwareProductId, version) {
+	let versionQuery = version ? `?version=${version}` : '';
+	return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}${versionQuery}`);
+}
+
+
+
+const SoftwareProductActionHelper = {
+
+	fetchProcessesList(dispatch, {softwareProductId, version}) {
+
+		dispatch({
+			type: actionTypes.FETCH_SOFTWARE_PRODUCT_PROCESSES,
+			processesList: []
+		});
+
+		return fetchProcesses(softwareProductId, version).then(response => {
+			dispatch({
+				type: actionTypes.FETCH_SOFTWARE_PRODUCT_PROCESSES,
+				processesList: response.results
+			});
+		});
+	},
+	openEditor(dispatch, process = {}) {
+		dispatch({
+			type: actionTypes.SOFTWARE_PRODUCT_PROCESS_EDITOR_OPEN,
+			process
+		});
+	},
+
+	deleteProcess(dispatch, {process, softwareProductId}) {
+		return deleteProcess(softwareProductId, process.id).then(() => {
+			dispatch({
+				type: actionTypes.DELETE_SOFTWARE_PRODUCT_PROCESS,
+				processId: process.id
+			});
+		});
+
+	},
+
+	closeEditor(dispatch) {
+		dispatch({
+			type:actionTypes.SOFTWARE_PRODUCT_PROCESS_EDITOR_CLOSE
+		});
+	},
+
+	processEditorDataChanged(dispatch, {deltaData}) {
+		dispatch({
+			type: actionTypes.processEditor.DATA_CHANGED,
+			deltaData
+		});
+	},
+
+	saveProcess(dispatch, {softwareProductId, previousProcess, process}) {
+		if (previousProcess) {
+			return putProcess(softwareProductId, process).then(() => {
+				if (process.formData){
+					uploadFileToProcess(softwareProductId, process.id, process.formData);
+				}
+				dispatch({
+					type: actionTypes.EDIT_SOFTWARE_PRODUCT_PROCESS,
+					process
+				});
+			});
+		}
+		else {
+			return postProcess(softwareProductId, process).then(response => {
+				if (process.formData) {
+					uploadFileToProcess(softwareProductId, response.value, process.formData);
+				}
+				dispatch({
+					type: actionTypes.ADD_SOFTWARE_PRODUCT_PROCESS,
+					process: {
+						...process,
+						id: response.value
+					}
+				});
+			});
+		}
+	},
+
+	hideDeleteConfirm(dispatch) {
+		dispatch({
+			type: actionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM,
+			processToDelete: false
+		});
+	},
+
+	openDeleteProcessesConfirm(dispatch, {process} ) {
+		dispatch({
+			type: actionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM,
+			processToDelete: process
+		});
+	}
+
+};
+
+export default SoftwareProductActionHelper;
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx
new file mode 100644
index 0000000..0159352
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx
@@ -0,0 +1,45 @@
+import React from 'react';
+import {connect} from 'react-redux';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
+import SoftwareProductProcessesActionHelper from './SoftwareProductProcessesActionHelper.js';
+
+function renderMsg(processToDelete) {
+	let name = processToDelete ? processToDelete.name : '';
+	let msg = i18n('Are you sure you want to delete "{name}"?', {name});
+	return (
+		<div>
+			<p>{msg}</p>
+		</div>
+	);
+};
+
+const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductEditor, softwareProductProcesses} = softwareProduct;
+	let {processToDelete} = softwareProductProcesses;
+	let softwareProductId = softwareProductEditor.data.id;
+
+	const show = processToDelete !== false;
+	return {
+		show,
+		title: i18n('Warning!'),
+		type: 'warning',
+		msg: renderMsg(processToDelete),
+		confirmationDetails: {processToDelete, softwareProductId}
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onConfirmed: ({processToDelete, softwareProductId}) => {
+			SoftwareProductProcessesActionHelper.deleteProcess(dispatch, {process: processToDelete, softwareProductId});
+			SoftwareProductProcessesActionHelper.hideDeleteConfirm(dispatch);
+		},
+		onDeclined: () => {
+			SoftwareProductProcessesActionHelper.hideDeleteConfirm(dispatch);
+		}
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js
new file mode 100644
index 0000000..63f3067
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+	ADD_SOFTWARE_PRODUCT_PROCESS: null,
+	EDIT_SOFTWARE_PRODUCT_PROCESS: null,
+	DELETE_SOFTWARE_PRODUCT_PROCESS: null,
+	SOFTWARE_PRODUCT_PROCESS_EDITOR_OPEN: null,
+	SOFTWARE_PRODUCT_PROCESS_EDITOR_CLOSE: null,
+	FETCH_SOFTWARE_PRODUCT_PROCESSES: null,
+	SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM: null,
+	processEditor: {
+		DATA_CHANGED: null
+	}
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js
new file mode 100644
index 0000000..8dc48c5
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductProcessesActionHelper from './SoftwareProductProcessesActionHelper';
+import SoftwareProductProcessesEditorView from './SoftwareProductProcessesEditorView.jsx';
+
+const mapStateToProps = ({softwareProduct}) => {
+	let {softwareProductProcesses: {processesList, processesEditor}} = softwareProduct;
+	let {data} = processesEditor;
+
+	let previousData;
+	const processId = data ? data.id : null;
+	if(processId) {
+		previousData = processesList.find(process => process.id === processId);
+	}
+
+	return {
+		data,
+		previousData
+	};
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId}) => {
+	return {
+		onDataChanged: deltaData => SoftwareProductProcessesActionHelper.processEditorDataChanged(dispatch, {deltaData}),
+		onSubmit: ({previousProcess, process}) => {
+			SoftwareProductProcessesActionHelper.closeEditor(dispatch);
+			SoftwareProductProcessesActionHelper.saveProcess(dispatch, {softwareProductId, previousProcess, process});
+		},
+		onClose: () => SoftwareProductProcessesActionHelper.closeEditor(dispatch)
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(SoftwareProductProcessesEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js
new file mode 100644
index 0000000..cae25e2
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductProcessesConstants.js';
+
+export default (state = {}, action) => {
+	switch (action.type) {
+		case actionTypes.SOFTWARE_PRODUCT_PROCESS_EDITOR_OPEN:
+			return {
+				...state,
+				data: action.process
+			};
+		case actionTypes.SOFTWARE_PRODUCT_PROCESS_EDITOR_CLOSE:
+			return {};
+
+		case actionTypes.processEditor.DATA_CHANGED:
+			return {
+				...state,
+				data: {
+					...state.data,
+					...action.deltaData
+				}
+			};
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx
new file mode 100644
index 0000000..c2c4aff
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx
@@ -0,0 +1,122 @@
+import React from 'react';
+import Dropzone from 'react-dropzone';
+import classnames from 'classnames';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+
+const SoftwareProductProcessEditorPropType = React.PropTypes.shape({
+	id: React.PropTypes.string,
+	name: React.PropTypes.string,
+	description: React.PropTypes.string,
+	artifactName: React.PropTypes.string
+});
+
+class SoftwareProductProcessesEditorView extends React.Component {
+
+	state = {
+		dragging: false,
+		files: []
+	};
+
+	static propTypes = {
+		data: SoftwareProductProcessEditorPropType,
+		previousData: SoftwareProductProcessEditorPropType,
+		isReadOnlyMode: React.PropTypes.bool,
+		onDataChanged: React.PropTypes.func,
+		onSubmit: React.PropTypes.func,
+		onClose: React.PropTypes.func
+	};
+
+	render() {
+		let {data = {}, isReadOnlyMode, onDataChanged, onClose} = this.props;
+		let {name, description, artifactName} = data;
+		return (
+			<ValidationForm
+				ref='validationForm'
+				hasButtons={true}
+				labledButtons={true}
+				isReadOnlyMode={isReadOnlyMode}
+				onSubmit={ () => this.submit() }
+				onReset={ () => onClose() }
+				className='vsp-processes-editor'>
+				<div className={classnames('vsp-processes-editor-data', {'disabled': isReadOnlyMode})}>
+					<Dropzone
+						className={classnames('vsp-process-dropzone-view', {'active-dragging': this.state.dragging})}
+						onDrop={files => this.handleImportSubmit(files)}
+						onDragEnter={() => this.setState({dragging: true})}
+						onDragLeave={() => this.setState({dragging: false})}
+						multiple={false}
+						disableClick={true}
+						ref='processEditorFileInput'
+						name='processEditorFileInput'
+						accept='*.*'>
+						<div className='row'>
+							<div className='col-md-6'>
+								<ValidationInput
+									onChange={name => onDataChanged({name})}
+									label={i18n('Name')}
+									value={name}
+									validations={{validateName: true, maxLength: 120, required: true}}
+									type='text'/>
+								<ValidationInput
+									label={i18n('Artifacts')}
+									value={artifactName}
+									type='text'
+									disabled/>
+							</div>
+							<div className='col-md-6'>
+								<div className='file-upload-box'>
+									<div className='drag-text'>{i18n('Drag & drop for upload')}</div>
+									<div className='or-text'>{i18n('or')}</div>
+									<div className='upload-btn primary-btn' onClick={() => this.refs.processEditorFileInput.open()}>
+										<span className='primary-btn-text'>{i18n('Select file')}</span>
+									</div>
+								</div>
+							</div>
+						</div>
+						<ValidationInput
+							onChange={description => onDataChanged({description})}
+							label={i18n('Notes')}
+							value={description}
+							name='vsp-process-description'
+							className='vsp-process-description'
+							validations={{maxLength: 1000}}
+							type='textarea'/>
+					</Dropzone>
+				</div>
+			</ValidationForm>
+		);
+	}
+
+	submit() {
+		const {data: process, previousData: previousProcess} = this.props;
+		let {files} = this.state;
+		let formData = false;
+		if (files.length) {
+			let file = files[0];
+			formData = new FormData();
+			formData.append('upload', file);
+		}
+
+		let updatedProcess = {
+			...process,
+			formData
+		};
+		this.props.onSubmit({process: updatedProcess, previousProcess});
+	}
+
+
+	handleImportSubmit(files) {
+		let {onDataChanged} = this.props;
+		this.setState({
+			dragging: false,
+			complete: '0',
+			files
+		});
+		onDataChanged({artifactName: files[0].name});
+	}
+}
+
+export default SoftwareProductProcessesEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js
new file mode 100644
index 0000000..619a2db
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './SoftwareProductProcessesConstants.js';
+
+export default (state = [], action) => {
+	switch (action.type) {
+		case actionTypes.FETCH_SOFTWARE_PRODUCT_PROCESSES:
+			return [...action.processesList];
+		case actionTypes.EDIT_SOFTWARE_PRODUCT_PROCESS:
+			const indexForEdit = state.findIndex(process => process.id === action.process.id);
+			return [...state.slice(0, indexForEdit), action.process, ...state.slice(indexForEdit + 1)];
+		case actionTypes.ADD_SOFTWARE_PRODUCT_PROCESS:
+			return [...state, action.process];
+		case actionTypes.DELETE_SOFTWARE_PRODUCT_PROCESS:
+			return state.filter(process => process.id !== action.processId);
+		default:
+			return state;
+	}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx
new file mode 100644
index 0000000..a2aa3d4
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx
@@ -0,0 +1,112 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+
+import SoftwareProductProcessesEditor from './SoftwareProductProcessesEditor.js';
+import SoftwareProductProcessesConfirmationModal  from './SoftwareProductProcessesConfirmationModal.jsx';
+
+
+class SoftwareProductProcessesView extends React.Component {
+
+	state = {
+		localFilter: ''
+	};
+
+	static propTypes = {
+		onAddProcess: React.PropTypes.func.isRequired,
+		onEditProcess: React.PropTypes.func.isRequired,
+		onDeleteProcess: React.PropTypes.func.isRequired,
+		isDisplayEditor: React.PropTypes.bool.isRequired,
+		isReadOnlyMode: React.PropTypes.bool.isRequired
+	};
+
+	render() {
+		let { currentSoftwareProduct} = this.props;
+		return (
+			<div className='software-product-landing-view-right-side vsp-processes-page'>
+				{this.renderEditor()}
+				{this.renderProcessList()}
+				<SoftwareProductProcessesConfirmationModal softwareProductId={currentSoftwareProduct.id}/>
+			</div>
+		);
+	}
+
+	renderEditor() {
+		let {currentSoftwareProduct: {id}, isModalInEditMode, isReadOnlyMode, isDisplayEditor} = this.props;
+		return (
+
+			<Modal show={isDisplayEditor} bsSize='large' animation={true}>
+				<Modal.Header>
+					<Modal.Title>{isModalInEditMode ? i18n('Edit Process Details') : i18n('Create New Process Details')}</Modal.Title>
+				</Modal.Header>
+				<Modal.Body className='edit-process-modal'>
+					<SoftwareProductProcessesEditor softwareProductId={id} isReadOnlyMode={isReadOnlyMode}/>
+				</Modal.Body>
+			</Modal>
+		);
+	}
+
+	renderProcessList() {
+		const {localFilter} = this.state;
+		let {onAddProcess, isReadOnlyMode} = this.props;
+
+		return (
+			<ListEditorView
+				plusButtonTitle={i18n('Add Process Details')}
+				filterValue={localFilter}
+				placeholder={i18n('Filter Process')}
+				onAdd={onAddProcess}
+				isReadOnlyMode={isReadOnlyMode}
+				onFilter={filter => this.setState({localFilter: filter})}>
+				{this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))}
+			</ListEditorView>
+		);
+	}
+
+	renderProcessListItem(process, isReadOnlyMode) {
+		let {id, name, description, artifactName = ''} = process;
+		let {onEditProcess, onDeleteProcess} =  this.props;
+		return (
+			<ListEditorItemView
+				key={id}
+				className='list-editor-item-view'
+				isReadOnlyMode={isReadOnlyMode}
+				onSelect={() => onEditProcess(process)}
+				onDelete={() => onDeleteProcess(process)}>
+
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Name')}</div>
+					<div className='name'>{name}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Artifact name')}</div>
+					<div className='artifact-name'>{artifactName}</div>
+				</div>
+				<div className='list-editor-item-view-field'>
+					<div className='title'>{i18n('Notes')}</div>
+					<div className='description'>{description}</div>
+				</div>
+			</ListEditorItemView>
+		);
+	}
+
+	filterList() {
+		let {processesList} = this.props;
+		let {localFilter} = this.state;
+
+		if (localFilter.trim()) {
+			const filter = new RegExp(escape(localFilter), 'i');
+			return processesList.filter(({name = '', description = ''}) => {
+				return escape(name).match(filter) || escape(description).match(filter);
+			});
+		}
+		else {
+			return processesList;
+		}
+	}
+}
+
+export default SoftwareProductProcessesView;