function asyncModel(oData) {
		var oModel = new JSONModel(oData);

		oModel.$$valueAsPromise = true;

		oModel.bindProperty = function () {
			var oBinding = JSONModel.prototype.bindProperty.apply(this, arguments);

			oBinding.checkUpdate = function () {
				var vValue = this._getValue();

				if (this.mParameters.$$valueAsPromise) {
					if (0 <= vValue && vValue < 10) { // eslint-disable-line yoda
						vValue = new Promise(function (resolve) {
							setTimeout(resolve.bind(null, vValue), vValue);
						});
					} else if (vValue instanceof Error) {
						vValue = Promise.reject(vValue);
					} else if (vValue !== `sync`) {
						vValue = Promise.resolve(vValue);
					}
				} else {
					vValue = NaN; // not yet available
				}
				this.oValue = vValue;
				this._fireChange({reason : `change`});
			};

			return oBinding;
		};

		oModel.bindList = function () {
			var oBinding = JSONModel.prototype.bindList.apply(this, arguments),
				fnGetContexts = oBinding.getContexts,
				bWaited = false;

			oBinding.enableExtendedChangeDetection = function (bDetectUpdates, vKey) {
				if (bDetectUpdates || vKey !== undefined) {
					throw new Error(`Unexpected: enableExtendedChangeDetection(` + bDetectUpdates
						+ `, ` + vKey + `)`);
				}
				this.bUseExtendedChangeDetection = true;
			};

			oBinding.getContexts = function () {
				var aContexts;

				if (bWaited) {
					return fnGetContexts.apply(this, arguments);
				}
				setTimeout(function () {
					bWaited = true;
					oBinding._fireChange({reason : ChangeReason.Change});
				}, 5);
				aContexts = [];
				if (this.bUseExtendedChangeDetection) {
					aContexts.dataRequested = true;
				}
				return aContexts;
			};

			return oBinding;
		};

		return oModel;
	}
Creates a new (JSON) model with the given data which is able to return a property binding's
value as a promise.

@param {object} oData
  The model's data, JSON style
@returns {sap.ui.model.json.JSONModel}
  An "async" JSON model