before() {
			this.__ignoreIsolatedCoverage__ = true;
		}
******************************************************************************************
[{
	sMethod: "_setRawValue",
	bInternalValues: false,
	bRawValues: true
}, {
	sMethod: "_setInternalValue",
	bInternalValues: true,
	bRawValues: false
}, {
	sMethod: "_setExternalValue",
	bInternalValues: false,
	bRawValues: false
}].forEach(function (oFixture) {
	QUnit.test(`setExternalValue /w async type and context changed for method ${oFixture.sMethod}`, function (assert) {
		const oBinding1 = {
			getBindingMode() {},
			getContext() {}
		};
		const oBinding2 = {
			getBindingMode() {},
			getContext() {}
		};
		const oCompositeBinding = {
			aBindings: [oBinding1, oBinding2],
			sInternalType: "string",
			bInternalValues: oFixture.bInternalValues,
			bRawValues: oFixture.bRawValues,
			oType: {
				getParseWithValues() {},
				parseValue() {},
				validateValue() {}
			},
			getDataState() {},
			getValidateValues() {},
			getValue() {}
		};
		const oDataState = {
			setInvalidValue() {},
			setValue() {}
		};
		this.mock(DataType).expects("getType").withExactArgs("string").returns("~oType");
		const oCompositeBindingMock = this.mock(oCompositeBinding);
		oCompositeBindingMock.expects("getDataState").withExactArgs().returns(oDataState);
		const oBindingMock1 = this.mock(oBinding1);
		oBindingMock1.expects("getContext").withExactArgs().returns("~oUpdateContext1");
		const oBindingMock2 = this.mock(oBinding2);
		oBindingMock2.expects("getContext").withExactArgs().returns("~oUpdateContext2");
		const oTypeMock = this.mock(oCompositeBinding.oType);
		oTypeMock.expects("getParseWithValues").withExactArgs().returns(false);
		oTypeMock.expects("parseValue")
			.withExactArgs("~vValue", "string", undefined)
			.returns(["~vParsedValue1", "~vParsedValue2"]);
		oCompositeBindingMock.expects("getValidateValues")
			.withExactArgs(["~vParsedValue1", "~vParsedValue2"])
			.returns("~aValidateValues");
		oTypeMock.expects("validateValue")
			.withExactArgs("~aValidateValues").returns(Promise.resolve());

		// code under test
		const oPromise = CompositeBinding.prototype.setExternalValue.call(oCompositeBinding, "~vValue");

		// After validation the contexts have changed due to the async nature of the type's validation
		oBindingMock1.expects("getContext").withExactArgs().returns("~oNewContext1");
		oBindingMock2.expects("getContext").withExactArgs().returns("~oNewContext1");
		oBinding1[oFixture.sMethod] = () => {};
		oBinding2[oFixture.sMethod] = () => {};
		oBindingMock1.expects("getBindingMode").withExactArgs().returns(BindingMode.TwoWay);
		oBindingMock1.expects(oFixture.sMethod).withExactArgs("~vParsedValue1" , "~oUpdateContext1");
		oBindingMock2.expects("getBindingMode").withExactArgs().returns(BindingMode.TwoWay);
		oBindingMock2.expects(oFixture.sMethod).withExactArgs("~vParsedValue2" , "~oUpdateContext2");
		const oDataStateMock = this.mock(oDataState);
		oDataStateMock.expects("setInvalidValue").withExactArgs(undefined);
		oCompositeBindingMock.expects("getValue").withExactArgs().returns("~vValue");
		oDataStateMock.expects("setValue").withExactArgs("~vValue");

		return oPromise.then((vResult) => {
			assert.strictEqual(vResult, undefined);
		});
	});
});

//*********************************************************************************************
[{
	sMethod: "_setRawValue",
	bInternalValues: false,
	bRawValues: true
}, {
	sMethod: "_setInternalValue",
	bInternalValues: true,
	bRawValues: false
}, {
	sMethod: "_setExternalValue",
	bInternalValues: false,
	bRawValues: false
}].forEach(function (oFixture) {
	const sTitle = `setExternalValue /w async type and w/o context changed for method ${oFixture.sMethod}`;
	QUnit.test(sTitle, function (assert) {
		const oBinding1 = {
			getBindingMode() {},
			getContext() {}
		};
		const oBinding2 = {
			getBindingMode() {},
			getContext() {}
		};
		const oCompositeBinding = {
			aBindings: [oBinding1, oBinding2],
			sInternalType: "string",
			bInternalValues: oFixture.bInternalValues,
			bRawValues: oFixture.bRawValues,
			oType: {
				getParseWithValues() {},
				parseValue() {},
				validateValue() {}
			},
			getDataState() {},
			getValidateValues() {},
			getValue() {}
		};
		const oDataState = {
			setInvalidValue() {},
			setValue() {}
		};
		this.mock(DataType).expects("getType").withExactArgs("string").returns("~oType");
		const oCompositeBindingMock = this.mock(oCompositeBinding);
		oCompositeBindingMock.expects("getDataState").withExactArgs().returns(oDataState);
		const oBindingMock1 = this.mock(oBinding1);
		oBindingMock1.expects("getContext").withExactArgs().returns("~oUpdateContext1");
		const oBindingMock2 = this.mock(oBinding2);
		oBindingMock2.expects("getContext").withExactArgs().returns("~oUpdateContext2");
		const oTypeMock = this.mock(oCompositeBinding.oType);
		oTypeMock.expects("getParseWithValues").withExactArgs().returns(false);
		oTypeMock.expects("parseValue")
			.withExactArgs("~vValue", "string", undefined)
			.returns(["~vParsedValue1", "~vParsedValue2"]);
		oCompositeBindingMock.expects("getValidateValues")
			.withExactArgs(["~vParsedValue1", "~vParsedValue2"])
			.returns("~aValidateValues");
		oTypeMock.expects("validateValue")
			.withExactArgs("~aValidateValues").returns(Promise.resolve());

		// code under test
		const oPromise = CompositeBinding.prototype.setExternalValue.call(oCompositeBinding, "~vValue");

		// After validation the contexts have changed due to the async nature of the type's validation
		oBindingMock1.expects("getContext").withExactArgs().returns("~oUpdateContext1");
		oBindingMock2.expects("getContext").withExactArgs().returns("~oUpdateContext2");
		oBinding1[oFixture.sMethod] = () => {};
		oBinding2[oFixture.sMethod] = () => {};
		oBindingMock1.expects("getBindingMode").withExactArgs().returns(BindingMode.TwoWay);
		oBindingMock1.expects(oFixture.sMethod).withExactArgs("~vParsedValue1" , undefined);
		oBindingMock2.expects("getBindingMode").withExactArgs().returns(BindingMode.TwoWay);
		oBindingMock2.expects(oFixture.sMethod).withExactArgs("~vParsedValue2" , undefined);
		const oDataStateMock = this.mock(oDataState);
		oDataStateMock.expects("setInvalidValue").withExactArgs(undefined);
		oCompositeBindingMock.expects("getValue").withExactArgs().returns("~vValue");
		oDataStateMock.expects("setValue").withExactArgs("~vValue");

		return oPromise.then((vResult) => {
			assert.strictEqual(vResult, undefined);
		});
	});
});

	QUnit.test("disabled methods", function(assert) {
		assert.equal(this.composite.getContext(), null, "getContext() always returns null");
		assert.equal(this.composite.getModel(), null, "getModel() always returns null");
		assert.equal(this.composite.getPath(), null, "getPath() always returns null");
	});

	QUnit.test("change event", function(assert) {
		this.composite.attachChange(function() {
			assert.equal(this.composite.getExternalValue(), "1 2 4");
		}.bind(this));
		this.model.setProperty("/c", 4);
	});

	QUnit.test("formatter function", function(assert) {
		this.composite.setFormatter(myFormatter);
		assert.equal(this.composite.getExternalValue(), "1-2-3");
		this.composite.setFormatter(myCalculator);
		assert.equal(this.composite.getExternalValue(), 6);
	});

	QUnit.test("composite type", function(assert) {
		this.composite.setType(new MyCompositeType());
		assert.equal(this.composite.getExternalValue(), "1,2,3");
		this.composite.setExternalValue("3,2,1");
		assert.equal(this.model.getProperty("/a"), 3,
			"setExternalValue() does change model value for contained bindings");
		assert.throws(function(){this.composite.setExternalValue("0,0,0");}.bind(this),
			ValidateException, "validation throws ValidateExpception for invalid values");
	});

	QUnit.test("async composite type", function(assert) {
		var that = this;
		this.composite.setType(new MyAsyncCompositeType());
		var p1 = this.composite.getExternalValue().then(function(oValue) {
			assert.equal(oValue, "1,2,3");
		});
		var p2 = this.composite.setExternalValue("3,2,1").then(function(oValue) {
			assert.equal(that.model.getProperty("/a"), 3,
				"setExternalValue() does change model value for contained bindings");
		});
		var p3 = this.composite.setExternalValue("0,0,0").catch(function(oException) {
			assert.ok(oException instanceof ValidateException, "Rejects with ValidateException for invalid values");
		});
		return Promise.all([p1, p2, p3]);
	});

	QUnit.test("with partial update", function(assert) {
		var oType = new MyPartialUpdateType();
		oType.validateValue = function(aValues) {
			assert.equal(aValues[0], 1, "validateValue is called with all values");
			assert.equal(aValues[1], 4, "validateValue is called with all values");
			assert.equal(aValues[2], 3, "validateValue is called with all values");
		};
		this.composite.setType(oType);
		this.composite.setExternalValue(4); // MyPartialUpdateType returns given value as second part
		assert.equal(this.model.getProperty("/a"), 1, "first value is unchanged");
		assert.equal(this.model.getProperty("/b"), 4, "second value is changed with partial update");
		assert.equal(this.model.getProperty("/c"), 3, "third value is unchanged");
	});

	QUnit.test("array type", function(assert) {
		this.composite.setType(null, "int[]");
		assert.deepEqual(this.composite.getExternalValue(), [1,2,3]);
		this.composite.setExternalValue([3,2,1]);
		assert.equal(this.model.getProperty("/a"), 3,
			"setExternalValue() does change model value for contained bindings");
	});

	QUnit.test("simple type", function(assert) {
		assert.throws(function(){this.composite.setType(new TypeFloat());}.bind(this),
			Error, "setting a simple type on a composite binding throws");
	});

	QUnit.test("suspend/resume", function(assert) {

		var done = assert.async();
		assert.equal(deepEqual(this.composite.getValue(), [1,2,3]), true,
			"getValue() returns array of bound model values");
		this.composite.attachChange(this, function() {
			assert.equal(deepEqual(this.getValue(), [666,2,3]), true, "getValue() returns array of bound model values");
			done();
		});
		this.composite.suspend();
		this.composite.setValue([3,2,1]);
		assert.equal(deepEqual(this.composite.getValue(), [1,2,3]), true,
			"getValue() returns array of bound model values");
		this.model.setProperty("/a",666);
		assert.equal(deepEqual(this.composite.getValue(), [1,2,3]), true,
			"getValue() returns array of bound model values");
		this.composite.resume();
	});

	//**********************************************************************************************
	QUnit.test("constructor", function (assert) {
		var aBindings = [],
			oBinding = new CompositeBinding(aBindings, "~bRawValues", "~bInternalValues");

		// CompositeBinding has its own #getModel and #getPath methods always returning null; values passed to the base
		// class constructor are not used there
		assert.strictEqual(oBinding.oModel, null, "model passed to PropertyBinding c'tor");
		assert.strictEqual(oBinding.sPath, "", "path passed to PropertyBinding c'tor");
		assert.strictEqual(oBinding.aValues, null);
		assert.strictEqual(oBinding.bRawValues, "~bRawValues");
		assert.strictEqual(oBinding.bPreventUpdate, false);
		assert.strictEqual(oBinding.bInternalValues, "~bInternalValues");
		assert.ok(oBinding.hasOwnProperty("aOriginalValues"));
		assert.strictEqual(oBinding.aOriginalValues, undefined);
		assert.ok(oBinding.hasOwnProperty("fnChangeHandler"));
		assert.strictEqual(oBinding.fnChangeHandler, undefined);
		assert.ok(oBinding.hasOwnProperty("fnDataStateChangeHandler"));
		assert.strictEqual(oBinding.fnDataStateChangeHandler, undefined);

	});

[{
	aModels : [{}, null /*static binding