async add(mPropertyBag) {
			if (!mPropertyBag.changes.length) {
				return Promise.resolve([]);
			}
			const oReferenceControl = (
				mPropertyBag.changes[0].selectorElement
				|| mPropertyBag.changes[0].selectorControl
			);
			const oAppComponent = Utils.getAppComponentForControl(oReferenceControl);
			const sFlexReference = FlexRuntimeInfoAPI.getFlexReference({element: oReferenceControl});
			const oVariantModel = oAppComponent.getModel(ControlVariantApplyAPI.getVariantModelName());
			const sLayer = Layer.USER;
			const aSuccessfulChanges = [];
			const mVMReferences = {};

			function createChanges() {
				const aChanges = [];
				const aChangesToBeAdded = [];
				return mPropertyBag.changes.reduce(function(pPromise, oPersonalizationChange) {
					return pPromise
					.then(function() {
						oPersonalizationChange.selectorControl = oPersonalizationChange.selectorElement;
						return checkChangeSpecificData(oPersonalizationChange, sLayer);
					})
					.then(function() {
						// Transient changes are always VM-independent
						if (!oPersonalizationChange.transient && !mPropertyBag.ignoreVariantManagement) {
							// check for preset variantReference
							if (!oPersonalizationChange.changeSpecificData.variantReference) {
								let sVariantManagementReference;
								const sSelectorControlId = oPersonalizationChange.selectorControl.getId();
								sVariantManagementReference = mVMReferences[sSelectorControlId] || getRelevantVariantManagementReference(
									oAppComponent,
									oPersonalizationChange.selectorControl,
									mPropertyBag.useStaticArea
								);
								if (!sVariantManagementReference && !mPropertyBag.useStaticArea) {
									// If not already found, look for a suitable VM control in the static area
									sVariantManagementReference = getRelevantVariantManagementReference(
										oAppComponent,
										oPersonalizationChange.selectorControl,
										true
									);
								}
								if (sVariantManagementReference) {
									mVMReferences[sSelectorControlId] = sVariantManagementReference;
									const sCurrentVariantReference = oVariantModel.oData[sVariantManagementReference].currentVariant;
									oPersonalizationChange.changeSpecificData.variantReference = sCurrentVariantReference;
								}
							}
						} else {
							// delete preset variantReference
							delete oPersonalizationChange.changeSpecificData.variantReference;
						}

						oPersonalizationChange.changeSpecificData = {
							...oPersonalizationChange.changeSpecificData,
							developerMode: false,
							layer: sLayer
						};
						return ChangesWriteAPI.create({
							changeSpecificData: oPersonalizationChange.changeSpecificData,
							selector: oPersonalizationChange.selectorControl
						});
					})
					.then(function(oCreatedChange) {
						if (!oPersonalizationChange.transient) {
							aChangesToBeAdded.push(oCreatedChange);
						}

						aChanges.push({
							changeInstance: oCreatedChange,
							selectorControl: oPersonalizationChange.selectorControl
						});
					})
					.catch(function(oError) {
						Log.error("A Change was not created successfully. Reason: ", oError.message);
					});
				}, Promise.resolve())
				.then(function() {
					UIChangeManager.addDirtyChanges(sFlexReference, aChangesToBeAdded, oAppComponent);
					return aChanges;
				})
				.catch(function(oError) {
					Log.error("Changes were not added successfully. Reason: ", oError.message);
				});
			}

			function applyChanges(aChanges) {
				return aChanges.reduce(function(pPromise, oChange) {
					return pPromise
					.then(function() {
						oChange.changeInstance.setQueuedForApply();
						return ChangesWriteAPI.apply({
							change: oChange.changeInstance,
							element: oChange.selectorControl
						});
					})
					.then(function(oResult) {
						if (oResult.success) {
							aSuccessfulChanges.push(oChange.changeInstance);
						} else {
							throw oResult.error || new Error("ChangesWriteAPI.apply failed with unspecified error");
						}
					})
					.catch(function(oError) {
						FlexObjectManager.deleteFlexObjects({
							reference: sFlexReference,
							flexObjects: [oChange.changeInstance]
						});
						Log.error("A Change was not applied successfully. Reason: ", oError.message);
					});
				}, Promise.resolve());
			}

			// Make sure to first create and add all changes so that change handlers
			// that rely on change batching in the applier can wait for them, e.g.
			// when adding multiple columns at once to a MDC table
			const aChanges = await createChanges();
			await applyChanges(aChanges);

			(mChangeCreationListeners[sFlexReference] || [])
			.forEach(function(fnCallback) {
				fnCallback(aSuccessfulChanges);
			});
			return aSuccessfulChanges;
		}
Creates personalization changes, adds them to the flex persistence (not yet saved) and applies them to the control.

@param {object} mPropertyBag - Object with parameters as properties
@param {sap.ui.fl.write.api.ControlPersonalizationWriteAPI.PersonalizationChange[]} mPropertyBag.changes - Array of control changes of type {@link sap.ui.fl.write.api.ControlPersonalizationWriteAPI.PersonalizationChange}
@param {boolean} [mPropertyBag.ignoreVariantManagement=false] - If flag is set to <code>true</code>, the changes will not belong to any variant, otherwise it will be detected if the changes are done in the context of variant mangement
@param {boolean} [mPropertyBag.useStaticArea=false] - If flag is set to true then the static area is used to determine the variant management control

@returns {Promise} Promise resolving to an array of successfully applied changes, after the changes have been written to the map of dirty changes (except transient changes) and applied to the control
@private
@ui5-restricted