src/sap.ui.core/src/sap/ui/core/util/XMLPreprocessor.js
function createContextInterface(oWithControl, mSettings, i, vBindingOrContext) {
		/*
		 * Returns the single binding or model context related to the current formatter call.
		 *
		 * @param {number} [iPart]
		 *   index of part in case of the root formatter of a composite binding
		 * @returns {sap.ui.model.Binding|sap.ui.model.Context}
		 *   single binding or model context
		 */
		function getBindingOrContext(iPart) {
			if (!vBindingOrContext) {
				// lazy initialization
				// BEWARE: this is not yet defined when createContextInterface() is called!
				vBindingOrContext = oWithControl.getBinding("any");

				if (vBindingOrContext instanceof CompositeBinding) {
					vBindingOrContext = vBindingOrContext.getBindings();

					if (i !== undefined) { // not a root formatter
						vBindingOrContext = vBindingOrContext[i];
					}
				}
			}

			return Array.isArray(vBindingOrContext)
				? vBindingOrContext[iPart]
				: vBindingOrContext;
		}

		/**
		 * Returns the resolved path for the given single binding or model context.
		 *
		 * @param {sap.ui.model.Binding|sap.ui.model.Context} oBindingOrContext
		 *   single binding or model context
		 * @returns {string}
		 *   the resolved path
		 */
		function getPath(oBindingOrContext) {
			return oBindingOrContext instanceof Context
				? oBindingOrContext.getPath()
				: oBindingOrContext.getModel().resolve(
					oBindingOrContext.getPath(), oBindingOrContext.getContext());
		}

		/**
		 * Context interface provided by XML template processing as an additional first argument to
		 * any formatter function which opts in to this mechanism. Candidates for such formatter
		 * functions are all those used in binding expressions which are evaluated during XML
		 * template processing, including those used inside template instructions like
		 * <code>&lt;template:if></code>. The formatter function needs to be marked with a property
		 * <code>requiresIContext = true</code> to express that it requires this extended signature
		 * (compared to ordinary formatter functions). The usual arguments are provided after the
		 * first one (currently: the raw value from the model).
		 *
		 * This interface provides callback functions to access the model and path  which are needed
		 * to process OData V4 annotations. It initially offers a subset of methods from
		 * {@link sap.ui.model.Context} so that formatters might also be called with a context
		 * object for convenience, e.g. outside of XML template processing (see below for an
		 * exception to this rule).
		 *
		 * <b>Example:</b> Suppose you have a formatter function called "foo" like below and it is
		 * used within an XML template like
		 * <code>&lt;template:if test="{path: '...', formatter: 'foo'}"></code>.
		 * In this case <code>foo</code> is called with arguments <code>oInterface, vRawValue</code>
		 * such that
		 * <code>oInterface.getModel().getObject(oInterface.getPath()) === vRawValue</code> holds.
		 * <pre>
		 * window.foo = function (oInterface, vRawValue) {
		 *     //TODO ...
		 * };
		 * window.foo.requiresIContext = true;
		 * </pre>
		 *
		 * <b>Composite Binding Examples:</b> Suppose you have the same formatter function and it is
		 * used in a composite binding like <code>&lt;Text text="{path: 'Label', formatter: 'foo'}:
		 * {path: 'Value', formatter: 'foo'}"/></code>.
		 * In this case <code>oInterface.getPath()</code> refers to ".../Label" in the 1st call and
		 * ".../Value" in the 2nd call. This means each formatter call knows which part of the
		 * composite binding it belongs to and behaves just as if it was an ordinary binding.
		 *
		 * Suppose your formatter is not used within a part of the composite binding, but at the
		 * root of the composite binding in order to aggregate all parts like <code>
		 * &lt;Text text="{parts: [{path: 'Label'}, {path: 'Value'}], formatter: 'foo'}"/></code>.
		 * In this case <code>oInterface.getPath(0)</code> refers to ".../Label" and
		 * <code>oInterface.getPath(1)</code> refers to ".../Value". This means, the root formatter
		 * can access the ith part of the composite binding at will (since 1.31.0); see also
		 * {@link #.getInterface getInterface}.
		 * The function <code>foo</code> is called with arguments such that <code>
		 * oInterface.getModel(i).getObject(oInterface.getPath(i)) === arguments[i + 1]</code>
		 * holds.
		 * This use is not supported within an expression binding, that is, <code>&lt;Text
		 * text="{= ${parts: [{path: 'Label'}, {path: 'Value'}], formatter: 'foo'} }"/></code>
		 * does not work as expected because the property <code>requiresIContext = true</code> is
		 * ignored.
		 *
		 * To distinguish those two use cases, just check whether <code>oInterface.getModel() ===
		 * undefined</code>, in which case the formatter is called on root level of a composite
		 * binding. To find out the number of parts, probe for the smallest non-negative integer
		 * where <code>oInterface.getModel(i) === undefined</code>.
		 * This additional functionality is, of course, not available from
		 * {@link sap.ui.model.Context}, i.e. such formatters MUST be called with an instance of
		 * this context interface.
		 *
		 * @interface
		 * @name sap.ui.core.util.XMLPreprocessor.IContext
		 * @public
		 * @since 1.27.1
		 */
		return /** @lends sap.ui.core.util.XMLPreprocessor.IContext */ {
			/**
			 * Returns a context interface for the indicated part in case of the root formatter of a
			 * composite binding. The new interface provides access to the original settings, but
			 * only to the model and path of the indicated part:
			 * <pre>
			 * this.getInterface(i).getSetting(sName) === this.getSetting(sName);
			 * this.getInterface(i).getModel() === this.getModel(i);
			 * this.getInterface(i).getPath() === this.getPath(i);
			 * </pre>
			 *
			 * If a path is given, the new interface points to the resolved path as follows:
			 * <pre>
			 * this.getInterface(i, "foo/bar").getPath() === this.getPath(i) + "/foo/bar";
			 * this.getInterface(i, "/absolute/path").getPath() === "/absolute/path";
			 * </pre>
			 * A formatter which is not at the root level of a composite binding can also provide a
			 * path, but must not provide an index:
			 * <pre>
			 * this.getInterface("foo/bar").getPath() === this.getPath() + "/foo/bar";
			 * this.getInterface("/absolute/path").getPath() === "/absolute/path";
			 * </pre>
			 * Note that at least one argument must be present.
			 *
			 * @param {number} [iPart]
			 *   index of part in case of the root formatter of a composite binding
			 * @param {string} [sPath]
			 *   a path, interpreted relative to <code>this.getPath(iPart)</code>
			 * @returns {sap.ui.core.util.XMLPreprocessor.IContext}
			 *   the context interface related to the indicated part
			 * @throws {Error}
			 *   In case an index is given but the current interface does not belong to the root
			 *   formatter of a composite binding, or in case the given index is invalid (e.g.
			 *   missing or out of range), or in case a path is missing because no index is given,
			 *   or in case a path is given but the model cannot not create a binding context
			 *   synchronously
			 * @public
			 * @since 1.31.0
			 */
			getInterface : function (iPart, sPath) {
				var oBaseContext, oBindingOrContext, oModel;

				if (typeof iPart === "string") {
					sPath = iPart;
					iPart = undefined;
				}

				getBindingOrContext(); // initialize vBindingOrContext
				if (Array.isArray(vBindingOrContext)) {
					if (iPart >= 0 && iPart < vBindingOrContext.length) {
						oBindingOrContext = vBindingOrContext[iPart];
					} else {
						throw new Error("Invalid index of part: " + iPart);
					}
				} else if (iPart !== undefined) {
					throw new Error("Not the root formatter of a composite binding");
				} else if (sPath) {
					oBindingOrContext = vBindingOrContext;
				} else {
					throw new Error("Missing path");
				}

				if (sPath) {
					oModel = oBindingOrContext.getModel();
					if (sPath.charAt(0) !==  '/') { // relative path needs a base context
						oBaseContext = oBindingOrContext instanceof Context
							? oBindingOrContext
							: oModel.createBindingContext(oBindingOrContext.getPath(),
								oBindingOrContext.getContext());
					}
					oBindingOrContext = oModel.createBindingContext(sPath, oBaseContext);
					if (!oBindingOrContext) {
						throw new Error(
							"Model could not create binding context synchronously: " + oModel);
					}
				}

				return createContextInterface(null, mSettings, undefined, oBindingOrContext);
			},

			/**
			 * Returns the model related to the current formatter call.
			 *
			 * @param {number} [iPart]
			 *   index of part in case of the root formatter of a composite binding
			 *   (since 1.31.0)
			 * @returns {sap.ui.model.Model}
			 *   the model related to the current formatter call, or (since 1.31.0)
			 *   <code>undefined</code> in case of a root formatter if no <code>iPart</code> is
			 *   given or if <code>iPart</code> is out of range
			 * @public
			 */
			getModel : function (iPart) {
				var oBindingOrContext = getBindingOrContext(iPart);
				return oBindingOrContext && oBindingOrContext.getModel();
			},

			/**
			 * Returns the absolute path related to the current formatter call.
			 *
			 * @param {number} [iPart]
			 *   index of part in case of the root formatter of a composite binding (since 1.31.0)
			 * @returns {string}
			 *   the absolute path related to the current formatter call, or (since 1.31.0)
			 *   <code>undefined</code> in case of a root formatter if no <code>iPart</code> is
			 *   given or if <code>iPart</code> is out of range
			 * @public
			 */
			getPath : function (iPart) {
				var oBindingOrContext = getBindingOrContext(iPart);
				return oBindingOrContext && getPath(oBindingOrContext);
			},

			/**
			 * Returns the value of the setting with the given name which was provided to the XML
			 * template processing.
			 *
			 * @param {string} sName
			 *   the name of the setting
			 * @returns {any}
			 *   the value of the setting
			 * @throws {Error}
			 *   if the name is one of the reserved names: "bindingContexts", "models"
			 * @public
			 */
			getSetting : function (sName) {
				if (sName === "bindingContexts" || sName === "models") {
					throw new Error("Illegal argument: " + sName);
				}
				return mSettings[sName];
			}
		};
	}
function createContextInterface(oWithControl, mSettings, i, vBindingOrContext) {
		/*
		 * Returns the single binding or model context related to the current formatter call.
		 *
		 * @param {number} [iPart]
		 *   index of part in case of the root formatter of a composite binding
		 * @returns {sap.ui.model.Binding|sap.ui.model.Context}
		 *   single binding or model context
		 */
		function getBindingOrContext(iPart) {
			if (!vBindingOrContext) {
				// lazy initialization
				// BEWARE: this is not yet defined when createContextInterface() is called!
				vBindingOrContext = oWithControl.getBinding("any");

				if (vBindingOrContext instanceof CompositeBinding) {
					vBindingOrContext = vBindingOrContext.getBindings();

					if (i !== undefined) { // not a root formatter
						vBindingOrContext = vBindingOrContext[i];
					}
				}
			}

			return Array.isArray(vBindingOrContext)
				? vBindingOrContext[iPart]
				: vBindingOrContext;
		}

		/**
		 * Returns the resolved path for the given single binding or model context.
		 *
		 * @param {sap.ui.model.Binding|sap.ui.model.Context} oBindingOrContext
		 *   single binding or model context
		 * @returns {string}
		 *   the resolved path
		 */
		function getPath(oBindingOrContext) {
			return oBindingOrContext instanceof Context
				? oBindingOrContext.getPath()
				: oBindingOrContext.getModel().resolve(
					oBindingOrContext.getPath(), oBindingOrContext.getContext());
		}

		/**
		 * Context interface provided by XML template processing as an additional first argument to
		 * any formatter function which opts in to this mechanism. Candidates for such formatter
		 * functions are all those used in binding expressions which are evaluated during XML
		 * template processing, including those used inside template instructions like
		 * <code>&lt;template:if></code>. The formatter function needs to be marked with a property
		 * <code>requiresIContext = true</code> to express that it requires this extended signature
		 * (compared to ordinary formatter functions). The usual arguments are provided after the
		 * first one (currently: the raw value from the model).
		 *
		 * This interface provides callback functions to access the model and path  which are needed
		 * to process OData V4 annotations. It initially offers a subset of methods from
		 * {@link sap.ui.model.Context} so that formatters might also be called with a context
		 * object for convenience, e.g. outside of XML template processing (see below for an
		 * exception to this rule).
		 *
		 * <b>Example:</b> Suppose you have a formatter function called "foo" like below and it is
		 * used within an XML template like
		 * <code>&lt;template:if test="{path: '...', formatter: 'foo'}"></code>.
		 * In this case <code>foo</code> is called with arguments <code>oInterface, vRawValue</code>
		 * such that
		 * <code>oInterface.getModel().getObject(oInterface.getPath()) === vRawValue</code> holds.
		 * <pre>
		 * window.foo = function (oInterface, vRawValue) {
		 *     //TODO ...
		 * };
		 * window.foo.requiresIContext = true;
		 * </pre>
		 *
		 * <b>Composite Binding Examples:</b> Suppose you have the same formatter function and it is
		 * used in a composite binding like <code>&lt;Text text="{path: 'Label', formatter: 'foo'}:
		 * {path: 'Value', formatter: 'foo'}"/></code>.
		 * In this case <code>oInterface.getPath()</code> refers to ".../Label" in the 1st call and
		 * ".../Value" in the 2nd call. This means each formatter call knows which part of the
		 * composite binding it belongs to and behaves just as if it was an ordinary binding.
		 *
		 * Suppose your formatter is not used within a part of the composite binding, but at the
		 * root of the composite binding in order to aggregate all parts like <code>
		 * &lt;Text text="{parts: [{path: 'Label'}, {path: 'Value'}], formatter: 'foo'}"/></code>.
		 * In this case <code>oInterface.getPath(0)</code> refers to ".../Label" and
		 * <code>oInterface.getPath(1)</code> refers to ".../Value". This means, the root formatter
		 * can access the ith part of the composite binding at will (since 1.31.0); see also
		 * {@link #.getInterface getInterface}.
		 * The function <code>foo</code> is called with arguments such that <code>
		 * oInterface.getModel(i).getObject(oInterface.getPath(i)) === arguments[i + 1]</code>
		 * holds.
		 * This use is not supported within an expression binding, that is, <code>&lt;Text
		 * text="{= ${parts: [{path: 'Label'}, {path: 'Value'}], formatter: 'foo'} }"/></code>
		 * does not work as expected because the property <code>requiresIContext = true</code> is
		 * ignored.
		 *
		 * To distinguish those two use cases, just check whether <code>oInterface.getModel() ===
		 * undefined</code>, in which case the formatter is called on root level of a composite
		 * binding. To find out the number of parts, probe for the smallest non-negative integer
		 * where <code>oInterface.getModel(i) === undefined</code>.
		 * This additional functionality is, of course, not available from
		 * {@link sap.ui.model.Context}, i.e. such formatters MUST be called with an instance of
		 * this context interface.
		 *
		 * @interface
		 * @name sap.ui.core.util.XMLPreprocessor.IContext
		 * @public
		 * @since 1.27.1
		 */
		return /** @lends sap.ui.core.util.XMLPreprocessor.IContext */ {
			/**
			 * Returns a context interface for the indicated part in case of the root formatter of a
			 * composite binding. The new interface provides access to the original settings, but
			 * only to the model and path of the indicated part:
			 * <pre>
			 * this.getInterface(i).getSetting(sName) === this.getSetting(sName);
			 * this.getInterface(i).getModel() === this.getModel(i);
			 * this.getInterface(i).getPath() === this.getPath(i);
			 * </pre>
			 *
			 * If a path is given, the new interface points to the resolved path as follows:
			 * <pre>
			 * this.getInterface(i, "foo/bar").getPath() === this.getPath(i) + "/foo/bar";
			 * this.getInterface(i, "/absolute/path").getPath() === "/absolute/path";
			 * </pre>
			 * A formatter which is not at the root level of a composite binding can also provide a
			 * path, but must not provide an index:
			 * <pre>
			 * this.getInterface("foo/bar").getPath() === this.getPath() + "/foo/bar";
			 * this.getInterface("/absolute/path").getPath() === "/absolute/path";
			 * </pre>
			 * Note that at least one argument must be present.
			 *
			 * @param {number} [iPart]
			 *   index of part in case of the root formatter of a composite binding
			 * @param {string} [sPath]
			 *   a path, interpreted relative to <code>this.getPath(iPart)</code>
			 * @returns {sap.ui.core.util.XMLPreprocessor.IContext}
			 *   the context interface related to the indicated part
			 * @throws {Error}
			 *   In case an index is given but the current interface does not belong to the root
			 *   formatter of a composite binding, or in case the given index is invalid (e.g.
			 *   missing or out of range), or in case a path is missing because no index is given,
			 *   or in case a path is given but the model cannot not create a binding context
			 *   synchronously
			 * @public
			 * @since 1.31.0
			 */
			getInterface : function (iPart, sPath) {
				var oBaseContext, oBindingOrContext, oModel;

				if (typeof iPart === "string") {
					sPath = iPart;
					iPart = undefined;
				}

				getBindingOrContext(); // initialize vBindingOrContext
				if (Array.isArray(vBindingOrContext)) {
					if (iPart >= 0 && iPart < vBindingOrContext.length) {
						oBindingOrContext = vBindingOrContext[iPart];
					} else {
						throw new Error("Invalid index of part: " + iPart);
					}
				} else if (iPart !== undefined) {
					throw new Error("Not the root formatter of a composite binding");
				} else if (sPath) {
					oBindingOrContext = vBindingOrContext;
				} else {
					throw new Error("Missing path");
				}

				if (sPath) {
					oModel = oBindingOrContext.getModel();
					if (sPath.charAt(0) !==  '/') { // relative path needs a base context
						oBaseContext = oBindingOrContext instanceof Context
							? oBindingOrContext
							: oModel.createBindingContext(oBindingOrContext.getPath(),
								oBindingOrContext.getContext());
					}
					oBindingOrContext = oModel.createBindingContext(sPath, oBaseContext);
					if (!oBindingOrContext) {
						throw new Error(
							"Model could not create binding context synchronously: " + oModel);
					}
				}

				return createContextInterface(null, mSettings, undefined, oBindingOrContext);
			},

			/**
			 * Returns the model related to the current formatter call.
			 *
			 * @param {number} [iPart]
			 *   index of part in case of the root formatter of a composite binding
			 *   (since 1.31.0)
			 * @returns {sap.ui.model.Model}
			 *   the model related to the current formatter call, or (since 1.31.0)
			 *   <code>undefined</code> in case of a root formatter if no <code>iPart</code> is
			 *   given or if <code>iPart</code> is out of range
			 * @public
			 */
			getModel : function (iPart) {
				var oBindingOrContext = getBindingOrContext(iPart);
				return oBindingOrContext && oBindingOrContext.getModel();
			},

			/**
			 * Returns the absolute path related to the current formatter call.
			 *
			 * @param {number} [iPart]
			 *   index of part in case of the root formatter of a composite binding (since 1.31.0)
			 * @returns {string}
			 *   the absolute path related to the current formatter call, or (since 1.31.0)
			 *   <code>undefined</code> in case of a root formatter if no <code>iPart</code> is
			 *   given or if <code>iPart</code> is out of range
			 * @public
			 */
			getPath : function (iPart) {
				var oBindingOrContext = getBindingOrContext(iPart);
				return oBindingOrContext && getPath(oBindingOrContext);
			},

			/**
			 * Returns the value of the setting with the given name which was provided to the XML
			 * template processing.
			 *
			 * @param {string} sName
			 *   the name of the setting
			 * @returns {any}
			 *   the value of the setting
			 * @throws {Error}
			 *   if the name is one of the reserved names: "bindingContexts", "models"
			 * @public
			 */
			getSetting : function (sName) {
				if (sName === "bindingContexts" || sName === "models") {
					throw new Error("Illegal argument: " + sName);
				}
				return mSettings[sName];
			}
		};
	}
function createContextInterface ( oWithControl , mSettings , i , vBindingOrContext ) { /*
		 * Returns the single binding or model context related to the current formatter call.
		 *
		 * @param {number} [iPart]
		 *   index of part in case of the root formatter of a composite binding
		 * @returns {sap.ui.model.Binding|sap.ui.model.Context}
		 *   single binding or model context
		 */ function getBindingOrContext ( iPart ) { if ( ! vBindingOrContext ) { // lazy initialization // BEWARE: this is not yet defined when createContextInterface() is called! vBindingOrContext = oWithControl . getBinding ( "any" ) ; if ( vBindingOrContext instanceof CompositeBinding ) { vBindingOrContext = vBindingOrContext . getBindings ( ) ; if ( i !== undefined ) { // not a root formatter vBindingOrContext = vBindingOrContext [ i ] ; } } } return Array . isArray ( vBindingOrContext ) ? vBindingOrContext [ iPart ] : vBindingOrContext ; } /**
		 * Returns the resolved path for the given single binding or model context.
		 *
		 * @param {sap.ui.model.Binding|sap.ui.model.Context} oBindingOrContext
		 *   single binding or model context
		 * @returns {string}
		 *   the resolved path
		 */ function getPath ( oBindingOrContext ) { return oBindingOrContext instanceof Context ? oBindingOrContext . getPath ( ) : oBindingOrContext . getModel ( ) . resolve ( oBindingOrContext . getPath ( ) , oBindingOrContext . getContext ( ) ) ; } /**
		 * Context interface provided by XML template processing as an additional first argument to
		 * any formatter function which opts in to this mechanism. Candidates for such formatter
		 * functions are all those used in binding expressions which are evaluated during XML
		 * template processing, including those used inside template instructions like
		 * <code>&lt;template:if></code>. The formatter function needs to be marked with a property
		 * <code>requiresIContext = true</code> to express that it requires this extended signature
		 * (compared to ordinary formatter functions). The usual arguments are provided after the
		 * first one (currently: the raw value from the model).
		 *
		 * This interface provides callback functions to access the model and path  which are needed
		 * to process OData V4 annotations. It initially offers a subset of methods from
		 * {@link sap.ui.model.Context} so that formatters might also be called with a context
		 * object for convenience, e.g. outside of XML template processing (see below for an
		 * exception to this rule).
		 *
		 * <b>Example:</b> Suppose you have a formatter function called "foo" like below and it is
		 * used within an XML template like
		 * <code>&lt;template:if test="{path: '...', formatter: 'foo'}"></code>.
		 * In this case <code>foo</code> is called with arguments <code>oInterface, vRawValue</code>
		 * such that
		 * <code>oInterface.getModel().getObject(oInterface.getPath()) === vRawValue</code> holds.
		 * <pre>
		 * window.foo = function (oInterface, vRawValue) {
		 *     //TODO ...
		 * };
		 * window.foo.requiresIContext = true;
		 * </pre>
		 *
		 * <b>Composite Binding Examples:</b> Suppose you have the same formatter function and it is
		 * used in a composite binding like <code>&lt;Text text="{path: 'Label', formatter: 'foo'}:
		 * {path: 'Value', formatter: 'foo'}"/></code>.
		 * In this case <code>oInterface.getPath()</code> refers to ".../Label" in the 1st call and
		 * ".../Value" in the 2nd call. This means each formatter call knows which part of the
		 * composite binding it belongs to and behaves just as if it was an ordinary binding.
		 *
		 * Suppose your formatter is not used within a part of the composite binding, but at the
		 * root of the composite binding in order to aggregate all parts like <code>
		 * &lt;Text text="{parts: [{path: 'Label'}, {path: 'Value'}], formatter: 'foo'}"/></code>.
		 * In this case <code>oInterface.getPath(0)</code> refers to ".../Label" and
		 * <code>oInterface.getPath(1)</code> refers to ".../Value". This means, the root formatter
		 * can access the ith part of the composite binding at will (since 1.31.0); see also
		 * {@link #.getInterface getInterface}.
		 * The function <code>foo</code> is called with arguments such that <code>
		 * oInterface.getModel(i).getObject(oInterface.getPath(i)) === arguments[i + 1]</code>
		 * holds.
		 * This use is not supported within an expression binding, that is, <code>&lt;Text
		 * text="{= ${parts: [{path: 'Label'}, {path: 'Value'}], formatter: 'foo'} }"/></code>
		 * does not work as expected because the property <code>requiresIContext = true</code> is
		 * ignored.
		 *
		 * To distinguish those two use cases, just check whether <code>oInterface.getModel() ===
		 * undefined</code>, in which case the formatter is called on root level of a composite
		 * binding. To find out the number of parts, probe for the smallest non-negative integer
		 * where <code>oInterface.getModel(i) === undefined</code>.
		 * This additional functionality is, of course, not available from
		 * {@link sap.ui.model.Context}, i.e. such formatters MUST be called with an instance of
		 * this context interface.
		 *
		 * @interface
		 * @name sap.ui.core.util.XMLPreprocessor.IContext
		 * @public
		 * @since 1.27.1
		 */ return /** @lends sap.ui.core.util.XMLPreprocessor.IContext */ { /**
			 * Returns a context interface for the indicated part in case of the root formatter of a
			 * composite binding. The new interface provides access to the original settings, but
			 * only to the model and path of the indicated part:
			 * <pre>
			 * this.getInterface(i).getSetting(sName) === this.getSetting(sName);
			 * this.getInterface(i).getModel() === this.getModel(i);
			 * this.getInterface(i).getPath() === this.getPath(i);
			 * </pre>
			 *
			 * If a path is given, the new interface points to the resolved path as follows:
			 * <pre>
			 * this.getInterface(i, "foo/bar").getPath() === this.getPath(i) + "/foo/bar";
			 * this.getInterface(i, "/absolute/path").getPath() === "/absolute/path";
			 * </pre>
			 * A formatter which is not at the root level of a composite binding can also provide a
			 * path, but must not provide an index:
			 * <pre>
			 * this.getInterface("foo/bar").getPath() === this.getPath() + "/foo/bar";
			 * this.getInterface("/absolute/path").getPath() === "/absolute/path";
			 * </pre>
			 * Note that at least one argument must be present.
			 *
			 * @param {number} [iPart]
			 *   index of part in case of the root formatter of a composite binding
			 * @param {string} [sPath]
			 *   a path, interpreted relative to <code>this.getPath(iPart)</code>
			 * @returns {sap.ui.core.util.XMLPreprocessor.IContext}
			 *   the context interface related to the indicated part
			 * @throws {Error}
			 *   In case an index is given but the current interface does not belong to the root
			 *   formatter of a composite binding, or in case the given index is invalid (e.g.
			 *   missing or out of range), or in case a path is missing because no index is given,
			 *   or in case a path is given but the model cannot not create a binding context
			 *   synchronously
			 * @public
			 * @since 1.31.0
			 */ getInterface : function ( iPart , sPath ) { var oBaseContext , oBindingOrContext , oModel ; if ( typeof iPart === "string" ) { sPath = iPart ; iPart = undefined ; } getBindingOrContext ( ) ; // initialize vBindingOrContext if ( Array . isArray ( vBindingOrContext ) ) { if ( iPart >= 0 && iPart < vBindingOrContext . length ) { oBindingOrContext = vBindingOrContext [ iPart ] ; } else { throw new Error ( "Invalid index of part: " + iPart ) ; } } else if ( iPart !== undefined ) { throw new Error ( "Not the root formatter of a composite binding" ) ; } else if ( sPath ) { oBindingOrContext = vBindingOrContext ; } else { throw new Error ( "Missing path" ) ; } if ( sPath ) { oModel = oBindingOrContext . getModel ( ) ; if ( sPath . charAt ( 0 ) !== '/' ) { // relative path needs a base context oBaseContext = oBindingOrContext instanceof Context ? oBindingOrContext : oModel . createBindingContext ( oBindingOrContext . getPath ( ) , oBindingOrContext . getContext ( ) ) ; } oBindingOrContext = oModel . createBindingContext ( sPath , oBaseContext ) ; if ( ! oBindingOrContext ) { throw new Error ( "Model could not create binding context synchronously: " + oModel ) ; } } return createContextInterface ( null , mSettings , undefined , oBindingOrContext ) ; } , /**
			 * Returns the model related to the current formatter call.
			 *
			 * @param {number} [iPart]
			 *   index of part in case of the root formatter of a composite binding
			 *   (since 1.31.0)
			 * @returns {sap.ui.model.Model}
			 *   the model related to the current formatter call, or (since 1.31.0)
			 *   <code>undefined</code> in case of a root formatter if no <code>iPart</code> is
			 *   given or if <code>iPart</code> is out of range
			 * @public
			 */ getModel : function ( iPart ) { var oBindingOrContext = getBindingOrContext ( iPart ) ; return oBindingOrContext && oBindingOrContext . getModel ( ) ; } , /**
			 * Returns the absolute path related to the current formatter call.
			 *
			 * @param {number} [iPart]
			 *   index of part in case of the root formatter of a composite binding (since 1.31.0)
			 * @returns {string}
			 *   the absolute path related to the current formatter call, or (since 1.31.0)
			 *   <code>undefined</code> in case of a root formatter if no <code>iPart</code> is
			 *   given or if <code>iPart</code> is out of range
			 * @public
			 */ getPath : function ( iPart ) { var oBindingOrContext = getBindingOrContext ( iPart ) ; return oBindingOrContext && getPath ( oBindingOrContext ) ; } , /**
			 * Returns the value of the setting with the given name which was provided to the XML
			 * template processing.
			 *
			 * @param {string} sName
			 *   the name of the setting
			 * @returns {any}
			 *   the value of the setting
			 * @throws {Error}
			 *   if the name is one of the reserved names: "bindingContexts", "models"
			 * @public
			 */ getSetting : function ( sName ) { if ( sName === "bindingContexts" || sName === "models" ) { throw new Error ( "Illegal argument: " + sName ) ; } return mSettings [ sName ] ; } } ; }
Creates the context interface for a call to the given control's formatter of the binding part
with given index.

@param {sap.ui.core.util._with} oWithControl
the "with" control
@param {object} mSettings
map/JSON-object with initial property values, etc.
@param {number} [i]
index of part inside a composite binding
@param {sap.ui.model.Binding|sap.ui.model.Binding[]|sap.ui.model.Context}
[vBindingOrContext]
single binding or model context or array of parts; if this parameter is given,
"oWithControl" and "i" are ignored, else it is lazily computed from those two
@returns {sap.ui.core.util.XMLPreprocessor.IContext}
the callback interface
Creates the context interface for a call to the given control s formatter of the binding part with given index .