diff --git a/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx b/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx
new file mode 100644
index 0000000..3ac3fca
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx
@@ -0,0 +1,77 @@
+import React from 'react';
+import FontAwesome from 'react-fontawesome';
+import classnames from 'classnames';
+import Input from 'react-bootstrap/lib/Input';
+
+
+class ExpandableInput extends React.Component {
+	constructor(props){
+		super(props);
+		this.state = {showInput: false, value: ''};
+		this.toggleInput = this.toggleInput.bind(this);
+		this.handleFocus = this.handleFocus.bind(this);
+		this.handleInput = this.handleInput.bind(this);
+		this.handleClose = this.handleClose.bind(this);
+	}
+
+	toggleInput(){
+		if (!this.state.showInput){
+			this.searchInputNode.refs.input.focus();
+		} else {
+			this.setState({showInput: false});
+		}
+	}
+
+	handleInput(e){
+		let {onChange} = this.props;
+
+		this.setState({value: e.target.value});
+		onChange(e);
+	}
+
+	handleClose(){
+		this.handleInput({target: {value: ''}});
+		this.searchInputNode.refs.input.focus();
+	}
+
+	handleFocus(){
+		if (!this.state.showInput){
+			this.setState({showInput: true});
+		}
+	}
+
+	getValue(){
+		return this.state.value;
+	}
+
+	render(){
+		let {iconType} = this.props;
+
+		let inputClasses = classnames({
+			'expandable-active': this.state.showInput,
+			'expandable-not-active': !this.state.showInput
+		});
+
+		let iconClasses = classnames(
+			'expandable-icon',
+			{'expandable-icon-active': this.state.showInput}
+		);
+
+		return (
+			<div className='expandable-input-wrapper'>
+				<Input
+					type='text'
+					value={this.state.value}
+					ref={(input) => this.searchInputNode = input}
+					className={inputClasses}
+					groupClassName='expandable-input-control'
+					onChange={e => this.handleInput(e)}
+					onFocus={this.handleFocus}/>
+				{this.state.showInput && this.state.value && <FontAwesome onClick={this.handleClose} name='close' className='expandable-close-button'/>}
+				{!this.state.value && <FontAwesome onClick={this.toggleInput} name={iconType} className={iconClasses}/>}
+			</div>
+		);
+	}
+}
+
+export default ExpandableInput;
diff --git a/openecomp-ui/src/nfvo-components/input/SelectInput.jsx b/openecomp-ui/src/nfvo-components/input/SelectInput.jsx
new file mode 100644
index 0000000..1036ac4
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/SelectInput.jsx
@@ -0,0 +1,52 @@
+/**
+ * The HTML structure here is aligned with bootstrap HTML structure for form elements.
+ * In this way we have proper styling and it is aligned with other form elements on screen.
+ *
+ * Select and MultiSelect options:
+ *
+ * label - the label to be shown which paired with the input
+ *
+ * all other "react-select" props - as documented on
+ * http://jedwatson.github.io/react-select/
+ * or
+ * https://github.com/JedWatson/react-select
+ */
+import React, {Component} from 'react';
+import Select from 'react-select';
+
+class SelectInput extends Component {
+
+	inputValue = [];
+
+	render() {
+		let {label, value, ...other} = this.props;
+		return (
+			<div className='validation-input-wrapper dropdown-multi-select'>
+				<div className='form-group'>
+					{label && <label className='control-label'>{label}</label>}
+					<Select ref='_myInput' onChange={value => this.onSelectChanged(value)} {...other} value={value} />
+				</div>
+			</div>
+		);
+	}
+
+	getValue() {
+		return this.inputValue && this.inputValue.length ? this.inputValue : '';
+	}
+
+	onSelectChanged(value) {
+		this.props.onMultiSelectChanged(value);
+	}
+
+	componentDidMount() {
+		let {value} = this.props;
+		this.inputValue = value ? value : [];
+	}
+	componentDidUpdate() {
+		if (this.inputValue !== this.props.value) {
+			this.inputValue = this.props.value;
+		}
+	}
+}
+
+export default SelectInput;
diff --git a/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx b/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx
new file mode 100644
index 0000000..873d3de
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx
@@ -0,0 +1,53 @@
+import React from 'react';
+
+export default
+class ToggleInput extends React.Component {
+
+	static propTypes = {
+		label: React.PropTypes.node,
+		value: React.PropTypes.bool,
+		onChange: React.PropTypes.func,
+		disabled: React.PropTypes.bool
+	}
+
+	static defaultProps = {
+		value: false,
+		label: ''
+	}
+
+	state = {
+		value: this.props.value
+	}
+
+	status() {
+		return this.state.value ? 'on' : 'off';
+	}
+
+	render() {
+		let {label, disabled} = this.props;
+		let checked = this.status() === 'on';
+		return (
+			<div className='toggle-input-wrapper form-group' onClick={!disabled && this.click}>
+				<div className='toggle-input-label'>{label}</div>
+				<div className='toggle-switch'>
+					<input className='toggle toggle-round-flat' type='checkbox' checked={checked} readOnly/>
+					<label></label>
+				</div>
+			</div>
+		);
+	}
+
+	click = () => {
+		let value = !this.state.value;
+		this.setState({value});
+
+		let onChange = this.props.onChange;
+		if (onChange) {
+			onChange(value);
+		}
+	}
+
+	getValue() {
+		return this.state.value;
+	}
+}
diff --git a/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx b/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
new file mode 100644
index 0000000..171bead
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
@@ -0,0 +1,132 @@
+import React from 'react';
+import FontAwesome from 'react-fontawesome';
+import Input from 'react-bootstrap/lib/Input.js';
+
+class DualListboxView extends React.Component {
+
+	static propTypes = {
+
+		availableList: React.PropTypes.arrayOf(React.PropTypes.shape({
+			id: React.PropTypes.string.isRequired,
+			name: React.PropTypes.string.isRequired
+		})),
+		filterTitle: React.PropTypes.shape({
+			left: React.PropTypes.string,
+			right: React.PropTypes.string
+		}),
+		selectedValuesList: React.PropTypes.arrayOf(React.PropTypes.string),
+
+		onChange: React.PropTypes.func.isRequired
+	};
+
+	static defaultProps = {
+		selectedValuesList: [],
+		availableList: [],
+		filterTitle: {
+			left: '',
+			right: ''
+		}
+	};
+
+	state = {
+		availableListFilter: '',
+		selectedValuesListFilter: ''
+	};
+
+	static contextTypes = {
+		isReadOnlyMode: React.PropTypes.bool
+	};
+
+	render() {
+		let {availableList, selectedValuesList, filterTitle} = this.props;
+		let {availableListFilter, selectedValuesListFilter} = this.state;
+		let isReadOnlyMode = this.context.isReadOnlyMode;
+
+		let unselectedList = availableList.filter(availableItem => !selectedValuesList.find(value => value === availableItem.id));
+		let selectedList = availableList.filter(availableItem => selectedValuesList.find(value => value === availableItem.id));
+		selectedList = selectedList.sort((a, b) => selectedValuesList.indexOf(a.id) - selectedValuesList.indexOf(b.id));
+
+		return (
+			<div className='dual-list-box'>
+				{this.renderListbox(filterTitle.left, unselectedList, {
+					value: availableListFilter,
+					ref: 'availableListFilter',
+					disabled: isReadOnlyMode,
+					onChange: () => this.setState({availableListFilter: this.refs.availableListFilter.getValue()})
+				}, {ref: 'availableValues', disabled: isReadOnlyMode})}
+				{this.renderOperationsBar(isReadOnlyMode)}
+				{this.renderListbox(filterTitle.right, selectedList, {
+					value: selectedValuesListFilter,
+					ref: 'selectedValuesListFilter',
+					disabled: isReadOnlyMode,
+					onChange: () => this.setState({selectedValuesListFilter: this.refs.selectedValuesListFilter.getValue()})
+				}, {ref: 'selectedValues', disabled: isReadOnlyMode})}
+			</div>
+		);
+	}
+
+	renderListbox(filterTitle, list, filterProps, props) {
+		let regExFilter = new RegExp(escape(filterProps.value), 'i');
+		let matchedItems = list.filter(item => item.name.match(regExFilter));
+		let unMatchedItems = list.filter(item => !item.name.match(regExFilter));
+
+
+		return (
+			<div className='dual-search-multi-select-section'>
+				<p>{filterTitle}</p>
+				<div className='dual-text-box-search search-wrapper'>
+					<Input name='search-input-control' type='text' groupClassName='search-input-control' {...filterProps}/>
+					<FontAwesome name='search' className='search-icon'/>
+				</div>
+				<Input
+					multiple
+					groupClassName='dual-list-box-multi-select'
+					type='select'
+					name='dual-list-box-multi-select'
+					{...props}>
+					{matchedItems.map(item => this.renderOption(item.id, item.name))}
+					{matchedItems.length && unMatchedItems.length && <option style={{pointerEvents: 'none'}}>--------------------</option>}
+					{unMatchedItems.map(item => this.renderOption(item.id, item.name))}
+				</Input>
+			</div>
+		);
+	}
+
+	renderOption(value, name) {
+		return (<option className='dual-list-box-multi-select-text' key={value} value={value}>{name}</option>);
+	}
+
+	renderOperationsBar(isReadOnlyMode) {
+		return (
+			<div className={`dual-list-options-bar${isReadOnlyMode ? ' disabled' : ''}`}>
+				{this.renderOperationBarButton(() => this.addToSelectedList(), 'angle-right')}
+				{this.renderOperationBarButton(() => this.removeFromSelectedList(), 'angle-left')}
+				{this.renderOperationBarButton(() => this.addAllToSelectedList(), 'angle-double-right')}
+				{this.renderOperationBarButton(() => this.removeAllFromSelectedList(), 'angle-double-left')}
+			</div>
+		);
+	}
+
+	renderOperationBarButton(onClick, fontAwesomeIconName){
+		return (<div className='dual-list-option' onClick={onClick}><FontAwesome name={fontAwesomeIconName}/></div>);
+	}
+
+	addToSelectedList() {
+		this.props.onChange(this.props.selectedValuesList.concat(this.refs.availableValues.getValue()));
+	}
+
+	removeFromSelectedList() {
+		const selectedValues = this.refs.selectedValues.getValue();
+		this.props.onChange(this.props.selectedValuesList.filter(value => !selectedValues.find(selectedValue => selectedValue === value)));
+	}
+
+	addAllToSelectedList() {
+		this.props.onChange(this.props.availableList.map(item => item.id));
+	}
+
+	removeAllFromSelectedList() {
+		this.props.onChange([]);
+	}
+}
+
+export default DualListboxView;
diff --git a/openecomp-ui/src/nfvo-components/input/inputOptions/InputOptions.jsx b/openecomp-ui/src/nfvo-components/input/inputOptions/InputOptions.jsx
new file mode 100644
index 0000000..5daaffe
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/inputOptions/InputOptions.jsx
@@ -0,0 +1,221 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import classNames from 'classnames';
+import Select from 'nfvo-components/input/SelectInput.jsx';
+
+export const other = {OTHER: 'Other'};
+
+class InputOptions extends React.Component {
+
+	static propTypes = {
+		values: React.PropTypes.arrayOf(React.PropTypes.shape({
+			enum: React.PropTypes.string,
+			title: React.PropTypes.string
+		})),
+		isEnabledOther: React.PropTypes.bool,
+		title: React.PropTypes.string,
+		selectedValue: React.PropTypes.string,
+		multiSelectedEnum: React.PropTypes.array,
+		selectedEnum: React.PropTypes.string,
+		otherValue: React.PropTypes.string,
+		onEnumChange: React.PropTypes.func,
+		onOtherChange: React.PropTypes.func,
+		isRequired: React.PropTypes.bool,
+		isMultiSelect: React.PropTypes.bool
+	};
+
+
+	static contextTypes = {
+		isReadOnlyMode: React.PropTypes.bool
+	};
+
+	state = {
+		otherInputDisabled: !this.props.otherValue
+	};
+
+	oldProps = {
+		selectedEnum: '',
+		otherValue: '',
+		multiSelectedEnum: []
+	};
+
+	render() {
+		let {label, isRequired, values, otherValue, onOtherChange, isMultiSelect, onBlur, multiSelectedEnum, selectedEnum, hasError, validations, children} = this.props;
+
+		let currentMultiSelectedEnum = [];
+		let currentSelectedEnum = '';
+		let {otherInputDisabled} = this.state;
+		if (isMultiSelect) {
+			currentMultiSelectedEnum = multiSelectedEnum;
+			if(!otherInputDisabled) {
+				currentSelectedEnum = multiSelectedEnum ? multiSelectedEnum.toString() : undefined;
+			}
+		}
+		else if(selectedEnum){
+			currentSelectedEnum = selectedEnum;
+		}
+
+		let isReadOnlyMode = this.context.isReadOnlyMode;
+
+		return(
+			<div className={classNames('form-group', {'required' : validations.required , 'has-error' : hasError})}>
+				{label && <label className='control-label'>{label}</label>}
+				{isMultiSelect && otherInputDisabled ?
+					<Select
+						ref='_myInput'
+						value={currentMultiSelectedEnum}
+						className='options-input'
+						clearable={false}
+						required={isRequired}
+						disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+						onBlur={() => onBlur()}
+						onMultiSelectChanged={value => this.multiSelectEnumChanged(value)}
+						options={this.renderMultiSelectOptions(values)}
+						multi/> :
+					<div className={classNames('input-options',{'has-error' : hasError})}>
+						<select
+							ref={'_myInput'}
+							label={label}
+							className='form-control input-options-select'
+							value={currentSelectedEnum}
+							style={{'width' : otherInputDisabled ? '100%' : '95px'}}
+							onBlur={() => onBlur()}
+							disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+							onChange={ value => this.enumChanged(value)}
+							type='select'>
+							{values && values.length && values.map(val => this.renderOptions(val))}
+							{onOtherChange && <option key='other' value={other.OTHER}>{i18n(other.OTHER)}</option>}
+							{children}
+						</select>
+
+						{!otherInputDisabled && <div className='input-options-separator'/>}
+						<input
+							className='form-control input-options-other'
+							placeholder={i18n('other')}
+							ref='_otherValue'
+							style={{'display' : otherInputDisabled ? 'none' : 'block'}}
+							disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+							value={otherValue || ''}
+							onBlur={() => onBlur()}
+							onChange={() => this.changedOtherInput()}/>
+					</div>
+				}
+			</div>
+		);
+	}
+
+	renderOptions(val){
+		return(
+			<option key={val.enum} value={val.enum}>{val.title}</option>
+		);
+	}
+
+
+	renderMultiSelectOptions(values) {
+		let {onOtherChange} = this.props;
+		let optionsList = [];
+		if (onOtherChange) {
+			optionsList = values.map(option => {
+				return {
+					label: option.title,
+					value: option.enum,
+				};
+			}).concat([{
+				label: i18n(other.OTHER),
+				value: i18n(other.OTHER),
+			}]);
+		}
+		else {
+			optionsList = values.map(option => {
+				return {
+					label: option.title,
+					value: option.enum,
+				};
+			});
+		}
+		if (optionsList.length > 0 && optionsList[0].value === '') {
+			optionsList.shift();
+		}
+		return optionsList;
+	}
+
+	getValue() {
+		let res = '';
+		let {isMultiSelect} = this.props;
+		let {otherInputDisabled} = this.state;
+
+		if (otherInputDisabled) {
+			res = isMultiSelect ? this.refs._myInput.getValue() : this.refs._myInput.value;
+		} else {
+			res = this.refs._otherValue.value;
+		}
+		return res;
+	}
+
+	enumChanged() {
+		let enumValue = this.refs._myInput.value;
+		let {onEnumChange, isMultiSelect, onChange} = this.props;
+		this.setState({
+			otherInputDisabled: enumValue !== other.OTHER
+		});
+
+		let value = isMultiSelect ? [enumValue] : enumValue;
+		if (onEnumChange) {
+			onEnumChange(value);
+		}
+		if (onChange) {
+			onChange(value);
+		}
+	}
+
+	multiSelectEnumChanged(enumValue) {
+		let {onEnumChange} = this.props;
+		let selectedValues = enumValue.map(enumVal => {
+			return enumVal.value;
+		});
+
+		if (this.state.otherInputDisabled === false) {
+			selectedValues.shift();
+		}
+		else if (selectedValues.includes(i18n(other.OTHER))) {
+			selectedValues = [i18n(other.OTHER)];
+		}
+
+		this.setState({
+			otherInputDisabled: !selectedValues.includes(i18n(other.OTHER))
+		});
+		onEnumChange(selectedValues);
+	}
+
+	changedOtherInput() {
+		let {onOtherChange} = this.props;
+		onOtherChange(this.refs._otherValue.value);
+	}
+
+	componentDidUpdate() {
+		let {otherValue, selectedEnum, onInputChange, multiSelectedEnum} = this.props;
+		if (this.oldProps.otherValue !== otherValue
+			|| this.oldProps.selectedEnum !== selectedEnum
+			|| this.oldProps.multiSelectedEnum !== multiSelectedEnum) {
+			this.oldProps = {
+				otherValue,
+				selectedEnum,
+				multiSelectedEnum
+			};
+			onInputChange();
+		}
+	}
+
+	static getTitleByName(values, name) {
+		for (let key of Object.keys(values)) {
+			let option = values[key].find(option => option.enum === name);
+			if (option) {
+				return option.title;
+			}
+		}
+		return name;
+	}
+
+}
+
+export default InputOptions;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
new file mode 100644
index 0000000..a87c8d6
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
@@ -0,0 +1,40 @@
+/**
+ * Holds the buttons for save/reset for forms.
+ * Used by the ValidationForm that changes the state of the buttons according to its own state.
+ *
+ * properties:
+ * labledButtons - whether or not to use labeled buttons or icons only
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Button from 'react-bootstrap/lib/Button.js';
+import FontAwesome from 'react-fontawesome';
+
+class ValidationButtons extends React.Component {
+
+	static propTypes = {
+		labledButtons: React.PropTypes.bool.isRequired,
+		isReadOnlyMode: React.PropTypes.bool
+	};
+
+	state = {
+		isValid: this.props.formValid
+	};
+
+	render() {
+		var submitBtn = this.props.labledButtons ? i18n('Save') : <FontAwesome className='check' name='check'/>;
+		var closeBtn = this.props.labledButtons ? i18n('Cancel') : <FontAwesome className='close' name='close'/>;
+		return (
+			<div className='validation-buttons'>
+				{!this.props.isReadOnlyMode ?
+					<div>
+						<Button  bsStyle='primary' ref='submitbutton' type='submit' disabled={!this.state.isValid}>{submitBtn}</Button>
+						<Button  type='reset'>{closeBtn}</Button>
+					</div>
+					: <Button  type='reset'>{i18n('Close')}</Button>
+				}
+			</div>
+		);
+	}
+}
+export default ValidationButtons;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx
new file mode 100644
index 0000000..098ccf1
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx
@@ -0,0 +1,200 @@
+/**
+ * ValidationForm should be used in order to have a form that handles it's internal validation state.
+ * All ValidationInputs inside the form are checked for validity and the styling and submit buttons
+ * are updated accordingly.
+ *
+ * The properties that ahould be given to the form:
+ * labledButtons - whether or not use icons only as the form default buttons or use buttons with labels
+ * onSubmit - function for click on the submit button
+ * onReset - function for click on the reset button
+ */
+import React from 'react';
+import JSONSchema from 'nfvo-utils/json/JSONSchema.js';
+import JSONPointer from 'nfvo-utils/json/JSONPointer.js';
+import ValidationButtons from './ValidationButtons.jsx';
+
+class ValidationForm extends React.Component {
+
+	static childContextTypes = {
+		validationParent: React.PropTypes.any,
+		isReadOnlyMode: React.PropTypes.bool,
+		validationSchema: React.PropTypes.instanceOf(JSONSchema),
+		validationData: React.PropTypes.object
+	};
+
+	static defaultProps = {
+		hasButtons : true,
+		onSubmit : null,
+		onReset :  null,
+		labledButtons: true,
+		onValidChange :  null,
+		isValid: true
+	};
+
+	static propTypes = {
+		isValid : React.PropTypes.bool,
+		isReadOnlyMode : React.PropTypes.bool,
+		hasButtons : React.PropTypes.bool,
+		onSubmit : React.PropTypes.func,
+		onReset : React.PropTypes.func,
+		labledButtons: React.PropTypes.bool,
+		onValidChange : React.PropTypes.func,
+		onValidityChanged: React.PropTypes.func,
+		schema: React.PropTypes.object,
+		data: React.PropTypes.object
+	};
+
+	state = {
+		isValid: this.props.isValid
+	};
+
+	constructor(props) {
+		super(props);
+		this.validationComponents = [];
+	}
+
+	componentWillMount() {
+		let {schema, data} = this.props;
+		if (schema) {
+			this.processSchema(schema, data);
+		}
+	}
+
+	componentWillReceiveProps(nextProps) {
+		let {schema, data} = this.props;
+		let {schema: nextSchema, data: nextData} = nextProps;
+
+		if (schema !== nextSchema || data !== nextData) {
+			if (!schema || !nextSchema) {
+				throw new Error('ValidationForm: dynamically adding/removing schema is not supported');
+			}
+
+			if (schema !== nextSchema) {
+				this.processSchema(nextSchema, nextData);
+			} else {
+				this.setState({data: nextData});
+			}
+		}
+	}
+
+	processSchema(rawSchema, rawData) {
+		let schema = new JSONSchema();
+		schema.setSchema(rawSchema);
+		let data = schema.processData(rawData);
+		this.setState({
+			schema,
+			data
+		});
+	}
+
+	render() {
+		// eslint-disable-next-line no-unused-vars
+		let {isValid, isReadOnlyMode, hasButtons, onSubmit, labledButtons, onValidChange, onValidityChanged, schema, data, children, ...formProps} = this.props;
+		return (
+			<form {...formProps} onSubmit={event => this.handleFormSubmit(event)}>
+				<div className='validation-form-content'>{children}</div>
+				{hasButtons && <ValidationButtons labledButtons={labledButtons} ref='buttons' isReadOnlyMode={isReadOnlyMode}/>}
+			</form>
+		);
+	}
+
+	handleFormSubmit(event) {
+		event.preventDefault();
+		let isFormValid = true;
+		this.validationComponents.forEach(validationComponent => {
+			const isInputValid = validationComponent.validate().isValid;
+			isFormValid = isInputValid && isFormValid;
+		});
+		if(isFormValid && this.props.onSubmit) {
+			return this.props.onSubmit(event);
+		} else if(!isFormValid) {
+			this.setState({isValid: false});
+		}
+	}
+
+	componentWillUpdate(nextProps, nextState) {
+		if(this.state.isValid !== nextState.isValid && this.props.onValidityChanged) {
+			this.props.onValidityChanged(nextState.isValid);
+		}
+	}
+
+	componentDidUpdate(prevProps, prevState) {
+		// only handling this programatically if the validation of the form is done outside of the view
+		// (example with a form that is dependent on the state of other forms)
+		if (prevProps.isValid !== this.props.isValid) {
+			if (this.props.hasButtons) {
+				this.refs.buttons.setState({isValid: this.state.isValid});
+			}
+		} else if(this.state.isValid !== prevState.isValid) {
+			if (this.props.hasButtons) {
+				this.refs.buttons.setState({isValid: this.state.isValid});
+			}
+			// callback in case form is part of bigger picture in view
+			if (this.props.onValidChange) {
+				this.props.onValidChange(this.state.isValid);
+			}
+		}
+	}
+
+	componentDidMount() {
+		if (this.props.hasButtons) {
+			this.refs.buttons.setState({isValid: this.state.isValid});
+		}
+	}
+
+
+	getChildContext() {
+		return {
+			validationParent: this,
+			isReadOnlyMode: this.props.isReadOnlyMode,
+			validationSchema: this.state.schema,
+			validationData: this.state.data
+		};
+	}
+
+
+	/***
+	 * Used by ValidationInput in order to let the (parent) form know
+	 * the valid state. If there is a change in the state of the form,
+	 * the buttons will be updated.
+	 *
+	 * @param validationComponent
+	 * @param isValid
+	 */
+	childValidStateChanged(validationComponent, isValid) {
+		if (isValid !== this.state.isValid) {
+			let oldState = this.state.isValid;
+			let newState = isValid && this.validationComponents.filter(otherValidationComponent => validationComponent !== otherValidationComponent).every(otherValidationComponent => {
+				return otherValidationComponent.isValid();
+			});
+
+			if (oldState !== newState) {
+				this.setState({isValid: newState});
+			}
+		}
+	}
+
+	register(validationComponent) {
+		if (this.state.schema) {
+			// TODO: register
+		} else {
+			this.validationComponents.push(validationComponent);
+		}
+	}
+
+	unregister(validationComponent) {
+		this.childValidStateChanged(validationComponent, true);
+		this.validationComponents = this.validationComponents.filter(otherValidationComponent => validationComponent !== otherValidationComponent);
+	}
+
+	onValueChanged(pointer, value, isValid, error) {
+		this.props.onDataChanged({
+			data: JSONPointer.setValue(this.props.data, pointer, value),
+			isValid,
+			error
+		});
+	}
+}
+
+
+export default ValidationForm;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationInput.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationInput.jsx
new file mode 100644
index 0000000..0f14307
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/validation/ValidationInput.jsx
@@ -0,0 +1,509 @@
+/**
+ * Used for inputs on a validation form.
+ * All properties will be passed on to the input element.
+ *
+ * The following properties can be set for OOB validations and callbacks:
+ - required: Boolean:  Should be set to true if the input must have a value
+ - numeric: Boolean : Should be set to true id the input should be an integer
+ - onChange : Function :  Will be called to validate the value if the default validations are not sufficient, should return a boolean value
+ indicating whether the value is valid
+ - didUpdateCallback :Function: Will be called after the state has been updated and the component has rerendered. This can be used if
+ there are dependencies between inputs in a form.
+ *
+ * The following properties of the state can be set to determine
+ * the state of the input from outside components:
+ - isValid : Boolean - whether the value is valid
+ - value : value for the input field,
+ - disabled : Boolean,
+ - required : Boolean - whether the input value must be filled out.
+ */
+import React from 'react';
+import ReactDOM from 'react-dom';
+import Validator from 'validator';
+import FormGroup from 'react-bootstrap/lib/FormGroup.js';
+import Input from 'react-bootstrap/lib/Input.js';
+import Overlay from 'react-bootstrap/lib/Overlay.js';
+import Tooltip from 'react-bootstrap/lib/Tooltip.js';
+import isEqual from 'lodash/isEqual.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import JSONSchema from 'nfvo-utils/json/JSONSchema.js';
+import JSONPointer from 'nfvo-utils/json/JSONPointer.js';
+
+
+import InputOptions  from '../inputOptions/InputOptions.jsx';
+
+const globalValidationFunctions = {
+	required: value => value !== '',
+	maxLength: (value, length) => Validator.isLength(value, {max: length}),
+	minLength: (value, length) => Validator.isLength(value, {min: length}),
+	pattern: (value, pattern) => Validator.matches(value, pattern),
+	numeric: value => {
+		if (value === '') {
+			// to allow empty value which is not zero
+			return true;
+		}
+		return Validator.isNumeric(value);
+	},
+	maxValue: (value, maxValue) => value < maxValue,
+	minValue: (value, minValue) => value >= minValue,
+	alphanumeric: value => Validator.isAlphanumeric(value),
+	alphanumericWithSpaces: value => Validator.isAlphanumeric(value.replace(/ /g, '')),
+	validateName: value => Validator.isAlphanumeric(value.replace(/\s|\.|\_|\-/g, ''), 'en-US'),
+	validateVendorName: value => Validator.isAlphanumeric(value.replace(/[\x7F-\xFF]|\s/g, ''), 'en-US'),
+	freeEnglishText: value => Validator.isAlphanumeric(value.replace(/\s|\.|\_|\-|\,|\(|\)|\?/g, ''), 'en-US'),
+	email: value => Validator.isEmail(value),
+	ip: value => Validator.isIP(value),
+	url: value => Validator.isURL(value)
+};
+
+const globalValidationMessagingFunctions = {
+	required: () => i18n('Field is required'),
+	maxLength: (value, maxLength) => i18n('Field value has exceeded it\'s limit, {maxLength}. current length: {length}', {
+		length: value.length,
+		maxLength
+	}),
+	minLength: (value, minLength) => i18n('Field value should contain at least {minLength} characters.', {minLength}),
+	pattern: (value, pattern) => i18n('Field value should match the pattern: {pattern}.', {pattern}),
+	numeric: () => i18n('Field value should contain numbers only.'),
+	maxValue: (value, maxValue) => i18n('Field value should be less than: {maxValue}.', {maxValue}),
+	minValue: (value, minValue) => i18n('Field value should be at least: {minValue}.', {minValue}),
+	alphanumeric: () => i18n('Field value should contain letters or digits only.'),
+	alphanumericWithSpaces: () => i18n('Field value should contain letters, digits or spaces only.'),
+	validateName: ()=> i18n('Field value should contain English letters, digits , spaces, underscores, dashes and dots only.'),
+	validateVendorName: ()=> i18n('Field value should contain English letters digits and spaces only.'),
+	freeEnglishText: ()=> i18n('Field value should contain  English letters, digits , spaces, underscores, dashes and dots only.'),
+	email: () => i18n('Field value should be a valid email address.'),
+	ip: () => i18n('Field value should be a valid ip address.'),
+	url: () => i18n('Field value should be a valid url address.'),
+	general: () => i18n('Field value is invalid.')
+};
+
+class ValidationInput extends React.Component {
+
+	static contextTypes = {
+		validationParent: React.PropTypes.any,
+		isReadOnlyMode: React.PropTypes.bool,
+		validationSchema: React.PropTypes.instanceOf(JSONSchema),
+		validationData: React.PropTypes.object
+	};
+
+	static defaultProps = {
+		onChange: null,
+		disabled: null,
+		didUpdateCallback: null,
+		validations: {},
+		value: ''
+	};
+
+	static propTypes = {
+		type: React.PropTypes.string.isRequired,
+		onChange: React.PropTypes.func,
+		disabled: React.PropTypes.bool,
+		didUpdateCallback: React.PropTypes.func,
+		validations: React.PropTypes.object,
+		isMultiSelect: React.PropTypes.bool,
+		onOtherChange: React.PropTypes.func,
+		pointer: React.PropTypes.string
+	};
+
+
+	state = {
+		isValid: true,
+		style: null,
+		value: this.props.value,
+		error: {},
+		previousErrorMessage: '',
+		wasInvalid: false,
+		validations: this.props.validations,
+		isMultiSelect: this.props.isMultiSelect
+	};
+
+	componentWillMount() {
+		if (this.context.validationSchema) {
+			let {validationSchema: schema, validationData: data} = this.context,
+				{pointer} = this.props;
+
+			if (!schema.exists(pointer)) {
+				console.error(`Field doesn't exists in the schema ${pointer}`);
+			}
+
+			let value = JSONPointer.getValue(data, pointer);
+			if (value === undefined) {
+				value = schema.getDefault(pointer);
+				if (value === undefined) {
+					value = '';
+				}
+			}
+			this.setState({value});
+
+			let enums = schema.getEnum(pointer);
+			if (enums) {
+				let values = enums.map(value => ({enum: value, title: value, groupName: pointer})),
+					isMultiSelect = schema.isArray(pointer);
+
+				if (!isMultiSelect && this.props.type !== 'radiogroup') {
+					values = [{enum: '', title: i18n('Select...')}, ...values];
+				}
+				if (isMultiSelect && Array.isArray(value) && value.length === 0) {
+					value = '';
+				}
+
+				this.setState({
+					isMultiSelect,
+					values,
+					onEnumChange: value => this.changedInputOptions(value),
+					value
+				});
+			}
+
+			this.setState({validations: this.extractValidationsFromSchema(schema, pointer, this.props)});
+		}
+	}
+
+	extractValidationsFromSchema(schema, pointer, props) {
+		/* props are here to get precedence over the scheme definitions */
+		let validations = {};
+
+		if (schema.isRequired(pointer)) {
+			validations.required = true;
+		}
+
+		if (schema.isNumber(pointer)) {
+			validations.numeric = true;
+
+			const maxValue = props.validations.maxValue || schema.getMaxValue(pointer);
+			if (maxValue !== undefined) {
+				validations.maxValue = maxValue;
+			}
+
+			const minValue = props.validations.minValue || schema.getMinValue(pointer);
+			if (minValue !== undefined) {
+				validations.minValue = minValue;
+			}
+		}
+
+
+		if (schema.isString(pointer)) {
+
+			const pattern = schema.getPattern(pointer);
+			if (pattern) {
+				validations.pattern = pattern;
+			}
+
+			const maxLength = schema.getMaxLength(pointer);
+			if (maxLength !== undefined) {
+				validations.maxLength = maxLength;
+			}
+
+			const minLength = schema.getMinLength(pointer);
+			if (minLength !== undefined) {
+				validations.minLength = minLength;
+			}
+		}
+
+		return validations;
+	}
+
+	componentWillReceiveProps({value: nextValue, validations: nextValidations, pointer: nextPointer}, nextContext) {
+		const {validations, value} = this.props;
+		const validationsChanged = !isEqual(validations, nextValidations);
+		if (nextContext.validationSchema) {
+			if (this.props.pointer !== nextPointer ||
+				this.context.validationData !== nextContext.validationData) {
+				let currentValue = JSONPointer.getValue(this.context.validationData, this.props.pointer),
+					nextValue = JSONPointer.getValue(nextContext.validationData, nextPointer);
+				if(nextValue === undefined) {
+					nextValue = '';
+				}
+				if (this.state.isMultiSelect && Array.isArray(nextValue) && nextValue.length === 0) {
+					nextValue = '';
+				}
+				if (currentValue !== nextValue) {
+					this.setState({value: nextValue});
+				}
+				if (validationsChanged) {
+					this.setState({
+						validations: this.extractValidationsFromSchema(nextContext.validationSchema, nextPointer, {validations: nextValidations})
+					});
+				}
+			}
+		} else {
+			if (validationsChanged) {
+				this.setState({validations: nextValidations});
+			}
+			if (this.state.wasInvalid && (value !== nextValue || validationsChanged)) {
+				this.validate(nextValue, nextValidations);
+			} else if (value !== nextValue) {
+				this.setState({value: nextValue});
+			}
+		}
+	}
+
+	shouldTypeBeNumberBySchemeDefinition(pointer) {
+		return this.context.validationSchema &&
+			this.context.validationSchema.isNumber(pointer);
+	}
+
+	hasEnum(pointer) {
+		return this.context.validationSchema &&
+			this.context.validationSchema.getEnum(pointer);
+	}
+
+	render() {
+		let {value, isMultiSelect, values, onEnumChange, style, isValid, validations} = this.state;
+		let {onOtherChange, type, pointer} = this.props;
+		if (this.shouldTypeBeNumberBySchemeDefinition(pointer) && !this.hasEnum(pointer)) {
+			type = 'number';
+		}
+		let props = {...this.props};
+
+		let groupClasses = this.props.groupClassName || '';
+		if (validations.required) {
+			groupClasses += ' required';
+		}
+		let isReadOnlyMode = this.context.isReadOnlyMode;
+
+		if (value === true && (type === 'checkbox' || type === 'radio')) {
+			props.checked = true;
+		}
+		return (
+			<div className='validation-input-wrapper'>
+				{
+					!isMultiSelect && !onOtherChange && type !== 'select' && type !== 'radiogroup'
+					&& <Input
+						{...props}
+						type={type}
+						groupClassName={groupClasses}
+						ref={'_myInput'}
+						value={value}
+						disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+						bsStyle={style}
+						onChange={() => this.changedInput()}
+						onBlur={() => this.blurInput()}>
+						{this.props.children}
+					</Input>
+				}
+				{
+					type === 'radiogroup'
+					&& <FormGroup>
+						{
+							values.map(val =>
+								<Input disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+									inline={true}
+									ref={'_myInput' + (typeof val.enum === 'string' ? val.enum.replace(/\W/g, '_') : val.enum)}
+									value={val.enum} checked={value === val.enum}
+									type='radio' label={val.title}
+									name={val.groupName}
+									onChange={() => this.changedInput()}/>
+							)
+						}
+					</FormGroup>
+				}
+				{
+					(isMultiSelect || onOtherChange || type === 'select')
+					&& <InputOptions
+						onInputChange={() => this.changedInput()}
+						onBlur={() => this.blurInput()}
+						hasError={!isValid}
+						ref={'_myInput'}
+						isMultiSelect={isMultiSelect}
+						values={values}
+						onEnumChange={onEnumChange}
+						selectedEnum={value}
+						multiSelectedEnum={value}
+						{...props} />
+				}
+				{this.renderOverlay()}
+			</div>
+		);
+	}
+
+	renderOverlay() {
+		let position = 'right';
+		if (this.props.type === 'text'
+			|| this.props.type === 'email'
+			|| this.props.type === 'number'
+			|| this.props.type === 'password'
+
+		) {
+			position = 'bottom';
+		}
+
+		let validationMessage = this.state.error.message || this.state.previousErrorMessage;
+		return (
+			<Overlay
+				show={!this.state.isValid}
+				placement={position}
+				target={() => {
+					let target = ReactDOM.findDOMNode(this.refs._myInput);
+					return target.offsetParent ? target : undefined;
+				}}
+				container={this}>
+				<Tooltip
+					id={`error-${validationMessage.replace(' ', '-')}`}
+					className='validation-error-message'>
+					{validationMessage}
+				</Tooltip>
+			</Overlay>
+		);
+	}
+
+	componentDidMount() {
+		if (this.context.validationParent) {
+			this.context.validationParent.register(this);
+		}
+	}
+
+	componentDidUpdate(prevProps, prevState) {
+		if (this.context.validationParent) {
+			if (prevState.isValid !== this.state.isValid) {
+				this.context.validationParent.childValidStateChanged(this, this.state.isValid);
+			}
+		}
+		if (this.props.didUpdateCallback) {
+			this.props.didUpdateCallback();
+		}
+
+	}
+
+	componentWillUnmount() {
+		if (this.context.validationParent) {
+			this.context.validationParent.unregister(this);
+		}
+	}
+
+	isNumberInputElement() {
+		return this.props.type === 'number' || this.refs._myInput.props.type === 'number';
+	}
+
+	/***
+	 * Adding same method as the actual input component
+	 * @returns {*}
+	 */
+	getValue() {
+		if (this.props.type === 'checkbox') {
+			return this.refs._myInput.getChecked();
+		}
+		if (this.props.type === 'radiogroup') {
+			for (let key in this.refs) { // finding the value of the radio button that was checked
+				if (this.refs[key].getChecked()) {
+					return this.refs[key].getValue();
+				}
+			}
+		}
+		if (this.isNumberInputElement()) {
+			return Number(this.refs._myInput.getValue());
+		}
+
+		return this.refs._myInput.getValue();
+	}
+
+	resetValue() {
+		this.setState({value: this.props.value});
+	}
+
+
+	/***
+	 * internal method that validated the value. includes callback to the onChange method
+	 * @param value
+	 * @param validations - map containing validation id and the limitation describing the validation.
+	 * @returns {object}
+	 */
+	validateValue = (value, validations) => {
+		let {customValidationFunction} = validations;
+		let error = {};
+		let isValid = true;
+		for (let validation in validations) {
+			if ('customValidationFunction' !== validation) {
+				if (validations[validation]) {
+					if (!globalValidationFunctions[validation](value, validations[validation])) {
+						error.id = validation;
+						error.message = globalValidationMessagingFunctions[validation](value, validations[validation]);
+						isValid = false;
+						break;
+					}
+				}
+			} else {
+				let customValidationResult = customValidationFunction(value);
+
+				if (customValidationResult !== true) {
+					error.id = 'custom';
+					isValid = false;
+					if (typeof customValidationResult === 'string') {//custom validation error message supplied.
+						error.message = customValidationResult;
+					} else {
+						error.message = globalValidationMessagingFunctions.general();
+					}
+					break;
+				}
+
+
+			}
+		}
+
+		return {
+			isValid,
+			error
+		};
+	};
+
+	/***
+	 * Internal method that handles the change event of the input. validates and updates the state.
+	 */
+	changedInput() {
+
+		let {isValid, error} = this.state.wasInvalid ? this.validate() : this.state;
+		let onChange = this.props.onChange;
+		if (onChange) {
+			onChange(this.getValue(), isValid, error);
+		}
+		if (this.context.validationSchema) {
+			let value = this.getValue();
+			if (this.state.isMultiSelect && value === '') {
+				value = [];
+			}
+			if (this.shouldTypeBeNumberBySchemeDefinition(this.props.pointer)) {
+				value = Number(value);
+			}
+			this.context.validationParent.onValueChanged(this.props.pointer, value, isValid, error);
+		}
+	}
+
+	changedInputOptions(value) {
+		this.context.validationParent.onValueChanged(this.props.pointer, value, true);
+	}
+
+	blurInput() {
+		if (!this.state.wasInvalid) {
+			this.setState({wasInvalid: true});
+		}
+
+		let {isValid, error} = !this.state.wasInvalid ? this.validate() : this.state;
+		let onBlur = this.props.onBlur;
+		if (onBlur) {
+			onBlur(this.getValue(), isValid, error);
+		}
+	}
+
+	validate(value = this.getValue(), validations = this.state.validations) {
+		let validationStatus = this.validateValue(value, validations);
+		let {isValid, error} = validationStatus;
+		let _style = isValid ? null : 'error';
+		this.setState({
+			isValid,
+			error,
+			value,
+			previousErrorMessage: this.state.error.message || '',
+			style: _style,
+			wasInvalid: !isValid || this.state.wasInvalid
+		});
+
+		return validationStatus;
+	}
+
+	isValid() {
+		return this.state.isValid;
+	}
+
+}
+export default ValidationInput;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationTab.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationTab.jsx
new file mode 100644
index 0000000..6036518
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/validation/ValidationTab.jsx
@@ -0,0 +1,107 @@
+import React from 'react';
+import Tab from 'react-bootstrap/lib/Tab.js';
+
+export default
+class ValidationTab extends React.Component {
+
+	static propTypes = {
+		children: React.PropTypes.node,
+		eventKey: React.PropTypes.any.isRequired,
+		onValidationStateChange: React.PropTypes.func //This property is assigned dynamically via React.cloneElement. lookup ValidationTabs.jsx. therefore it cannot be stated as required!
+	};
+
+	constructor(props) {
+		super(props);
+		this.validationComponents = [];
+	}
+
+	static childContextTypes = {
+		validationParent: React.PropTypes.any
+	};
+
+	static contextTypes = {
+		validationParent: React.PropTypes.any
+	};
+
+	getChildContext() {
+		return {validationParent: this};
+	}
+
+	state = {
+		isValid: true,
+		notifyParent: false
+	};
+
+	componentDidMount() {
+		let validationParent = this.context.validationParent;
+		if (validationParent) {
+			validationParent.register(this);
+		}
+	}
+
+	componentWillUnmount() {
+		let validationParent = this.context.validationParent;
+		if (validationParent) {
+			validationParent.unregister(this);
+		}
+	}
+
+	register(validationComponent) {
+		this.validationComponents.push(validationComponent);
+	}
+
+	unregister(validationComponent) {
+		this.childValidStateChanged(validationComponent, true);
+		this.validationComponents = this.validationComponents.filter(otherValidationComponent => validationComponent !== otherValidationComponent);
+	}
+
+	notifyValidStateChangedToParent(isValid) {
+
+		let validationParent = this.context.validationParent;
+		if (validationParent) {
+			validationParent.childValidStateChanged(this, isValid);
+		}
+	}
+
+	childValidStateChanged(validationComponent, isValid) {
+
+		const currentValidState = this.state.isValid;
+		if (isValid !== currentValidState) {
+			let filteredValidationComponents = this.validationComponents.filter(otherValidationComponent => validationComponent !== otherValidationComponent);
+			let newValidState = isValid && filteredValidationComponents.every(otherValidationComponent => {
+				return otherValidationComponent.isValid();
+			});
+			this.setState({isValid: newValidState, notifyParent: true});
+		}
+	}
+
+	validate() {
+		let isValid = true;
+		this.validationComponents.forEach(validationComponent => {
+			const isValidationComponentValid = validationComponent.validate().isValid;
+			isValid = isValidationComponentValid && isValid;
+		});
+		this.setState({isValid, notifyParent: false});
+		return {isValid};
+	}
+
+	componentDidUpdate(prevProps, prevState) {
+		if(prevState.isValid !== this.state.isValid) {
+			if(this.state.notifyParent) {
+				this.notifyValidStateChangedToParent(this.state.isValid);
+			}
+			this.props.onValidationStateChange(this.props.eventKey, this.state.isValid);
+		}
+	}
+
+	isValid() {
+		return this.state.isValid;
+	}
+
+	render() {
+		let {children, ...tabProps} = this.props;
+		return (
+			<Tab {...tabProps}>{children}</Tab>
+		);
+	}
+}
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationTabs.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationTabs.jsx
new file mode 100644
index 0000000..6eda4b9
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/validation/ValidationTabs.jsx
@@ -0,0 +1,72 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import Tabs from 'react-bootstrap/lib/Tabs.js';
+import Overlay from 'react-bootstrap/lib/Overlay.js';
+import Tooltip from 'react-bootstrap/lib/Tooltip.js';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+export default
+class ValidationTab extends React.Component {
+
+	static propTypes = {
+		children: React.PropTypes.node
+	};
+
+	state = {
+		invalidTabs: []
+	};
+
+	cloneTab(element) {
+		const {invalidTabs} = this.state;
+		return React.cloneElement(
+			element,
+			{
+				key: element.props.eventKey,
+				tabClassName: invalidTabs.indexOf(element.props.eventKey) > -1 ? 'invalid-tab' : 'valid-tab',
+				onValidationStateChange: (eventKey, isValid) => this.validTabStateChanged(eventKey, isValid)
+			}
+		);
+	}
+
+	validTabStateChanged(eventKey, isValid) {
+		let {invalidTabs} = this.state;
+		let invalidTabIndex = invalidTabs.indexOf(eventKey);
+		if (isValid && invalidTabIndex > -1) {
+			this.setState({invalidTabs: invalidTabs.filter(otherEventKey => eventKey !== otherEventKey)});
+		} else if (!isValid && invalidTabIndex === -1) {
+			this.setState({invalidTabs: [...invalidTabs, eventKey]});
+		}
+	}
+
+	showTabsError() {
+		const {invalidTabs} = this.state;
+		return invalidTabs.length > 0 && (invalidTabs.length > 1 || invalidTabs[0] !== this.props.activeKey);
+	}
+
+	render() {
+		return (
+			<div>
+				<Tabs {...this.props} ref='tabsList'>
+					{this.props.children.map(element => this.cloneTab(element))}
+				</Tabs>
+				<Overlay
+					animation={false}
+					show={this.showTabsError()}
+					placement='bottom'
+					target={() => {
+						let target = ReactDOM.findDOMNode(this.refs.tabsList).querySelector('ul > li.invalid-tab:not(.active):nth-of-type(n)');
+						return target && target.offsetParent ? target : undefined;
+					}
+					}
+					container={this}>
+					<Tooltip
+						id='error-some-tabs-contain-errors'
+						className='validation-error-message'>
+						{i18n('One or more tabs are invalid')}
+					</Tooltip>
+				</Overlay>
+			</div>
+		);
+	}
+}
