function applyExtension(oController, oExtension, sLocalNamespace) {
			//create the controller extension object
			var sNamespace = oExtension.getMetadata().getName();
			var oControllerMetadata = oController.getMetadata();
			var oExtensions = oController["_sapui_Extensions"];
			var oInterface = oController.getInterface();
			var mLifecycleConfig = ControllerExtension.getMetadata().getLifecycleConfiguration();

			var oExtensionInfo = {
				namespace: sNamespace,
				extension: oExtension,
				reloadNeeded: false
			};

			oExtension._setController(oInterface); //only allow access to public methods of the main controller

			if (oExtension.getMetadata().hasOverrides()) {
				//override the original controller methods for the entries in the "override" setting of the controller extension
				var sExtensionOverride, oOrigExtensionInfo, oOrigExtensionMetadata, sOverrideMember,
					oOverrides = oExtension.getMetadata().getOverrides(),
					oStaticOverrides = oExtension.getMetadata().getStaticOverrides();

				//handle 'inline' overrides first
				for (sOverrideMember in oStaticOverrides) {
					oOrigExtensionMetadata = oExtension.getMetadata();
					if (!oOrigExtensionMetadata.isMethodFinal(sOverrideMember)) {
						ControllerExtension.overrideMethod(sOverrideMember, oExtension, oStaticOverrides, oExtension, oOrigExtensionMetadata.getOverrideExecution(sOverrideMember));
					}  else {
						future.errorThrows("Method '" + sOverrideMember + "' of extension '" + sNamespace + "' is flagged final and cannot be overridden by calling 'override'");
					}
				}
				//handle 'normal' overrides
				for (sOverrideMember in oOverrides) {
					if (sOverrideMember !== 'extension') {
						//handle overrides on controller and member extensions
						if (sOverrideMember in oExtension.base) {
							Log.debug("Overriding  member '" + sOverrideMember + "' of original controller.");
							var vMember = oOverrides[sOverrideMember];
							var fnOriginal = oController[sOverrideMember];
							//check for member extension
							if (typeof fnOriginal == "object" && typeof vMember == "object") {
								oOrigExtensionInfo = oExtensions[sOverrideMember];
								oOrigExtensionMetadata = oOrigExtensionInfo.extension.getMetadata();
								for (sExtensionOverride in vMember) {
									if (!oOrigExtensionMetadata.isMethodFinal(sExtensionOverride)) {
										ControllerExtension.overrideMethod(sExtensionOverride, fnOriginal, vMember, oExtension, oOrigExtensionMetadata.getOverrideExecution(sExtensionOverride));
									}  else {
										future.errorThrows("Method '" + sExtensionOverride + "' of extension '" + oOrigExtensionInfo.namespace + "' is flagged final and cannot be overridden by extension '" + sNamespace + "'");
									}
								}
							} else if (!oControllerMetadata.isMethodFinal(sOverrideMember)) {
								ControllerExtension.overrideMethod(sOverrideMember, oController, oOverrides, oExtension, oControllerMetadata.getOverrideExecution(sOverrideMember));
							} else {
								future.errorThrows("Method '" + sOverrideMember + "' of controller '" + oController.getMetadata().getName() + "' is flagged final and cannot be overridden by extension '" + sNamespace + "'");
							}
						} else if (sOverrideMember in mLifecycleConfig) {
							//apply lifecycle hooks even if they don't exist on controller
							ControllerExtension.overrideMethod(sOverrideMember, oController, oOverrides, oExtension, oControllerMetadata.getOverrideExecution(sOverrideMember));
						/* legacy support: hooks defined as null instead of a function and starting with 'extHook' must not be ignored.
							Some legacy applications defined possible extension hooks in this way. As ControllerExtensions rely on Interface usage
							legacy scenarios will break. */
						} else if (sOverrideMember.startsWith("extHook") && oController[sOverrideMember] === null) {
							ControllerExtension.overrideMethod(sOverrideMember, oController, oOverrides, oExtension);
						} else {
							future.errorThrows("Method '" + sOverrideMember + "' does not exist in controller " + oController.getMetadata().getName() + " and cannot be overridden");
						}
					}
					oExtensionInfo.reloadNeeded = true;
				}
				//handle non member extension overrides
				if (oOverrides && oOverrides.extension) {
					//allow to override methods of other controller extensions
					for (var sExtensionNamespace in oOverrides.extension) {
						oOrigExtensionMetadata = oExtensions[sExtensionNamespace].extension.getMetadata();
						var oOrigExtensionInterface = ObjectPath.create(sExtensionNamespace, oController.extension);
						var oOrigExtension = oExtensions[sExtensionNamespace].extension;
						var oExtensionOverrides = oOverrides.extension[sExtensionNamespace];
						for (sExtensionOverride in oExtensionOverrides) {
							if (!oOrigExtensionMetadata.isMethodFinal(sExtensionOverride)) {
								//override interface
								ControllerExtension.overrideMethod(sExtensionOverride, oOrigExtensionInterface, oExtensionOverrides, oExtension, oOrigExtensionMetadata.getOverrideExecution(sExtensionOverride));
								//override Extension so 'this' is working for overrides
								ControllerExtension.overrideMethod(sExtensionOverride, oOrigExtension, oExtensionOverrides, oExtension, oOrigExtensionMetadata.getOverrideExecution(sExtensionOverride));
							} else {
								future.errorThrows("Method '" + sExtensionOverride + "' of extension '" + sExtensionNamespace + "' is flagged final and cannot be overridden by extension '" + sNamespace + "'");
							}
						}
					}
				}
			}

			var oExtensionInterface = oExtension.getInterface();

			if (sLocalNamespace) {
				oExtensions[sLocalNamespace] = oExtensionInfo;
				oExtensionInfo.location = sLocalNamespace;
				oController[sLocalNamespace] = oExtensionInterface;
				oInterface[sLocalNamespace] = oExtensionInterface;
			} else {
				oExtensions[sNamespace] = oExtensionInfo;
				oExtensionInfo.location = "extension." + sNamespace;
				ObjectPath.set("extension." + sNamespace, oExtensionInterface, oController);
				ObjectPath.set("extension." + sNamespace, oExtensionInterface, oInterface);
			}
		}
Apply extension to controller

@param {sap.ui.core.mvc.Controller} oController The controller to extend
@param {sap.ui.core.mvc.ControllerExtension|object} oExtension The controller extension
@param {string} [sLocalNamespace] Extensions could be applied to a local namespace. Do so if passed
@private