<commit_before>/*!
 * ${copyright}
 */

// Provides control sap.m.IconTabHeader.
sap.ui.define(['jquery.sap.global', './library', 'sap/ui/core/Control', 'sap/ui/core/EnabledPropagator',
		'sap/ui/core/delegate/ItemNavigation', 'sap/ui/core/IconPool', 'sap/ui/core/delegate/ScrollEnablement',
		'./IconTabBarSelectList', './Button', './ResponsivePopover', './IconTabFilter'],
	function(jQuery, library, Control, EnabledPropagator,
				ItemNavigation, IconPool, ScrollEnablement,
				IconTabBarSelectList, Button, ResponsivePopover, IconTabFilter) {
	"use strict";

	/**
	 * Constructor for a new IconTabHeader.
	 *
	 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
	 * @param {object} [mSettings] Initial settings for the new control
	 *
	 * @class
	 * This control displays a number of IconTabFilters and IconTabSeparators. If the available horizontal
	 * space is exceeded, a horizontal scrolling appears.
	 * @extends sap.ui.core.Control
	 *
	 * @author SAP SE
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @alias sap.m.IconTabHeader
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var IconTabHeader = Control.extend("sap.m.IconTabHeader", /** @lends sap.m.IconTabHeader.prototype */ { metadata : {

		library : "sap.m",
		properties : {

			/**
			 * Defines whether the current selection is visualized.
			 * @deprecated As of 1.15.0.
			 * Regarding to changes of this control this property is not needed anymore.
			 */
			showSelection : {type : "boolean", group : "Misc", defaultValue : true, deprecated: true},

			/**
			 * Key of the selected item.
			 *
			 * If the key has no corresponding aggregated item, no changes will apply.
			 * If duplicate keys exists the first item matching, the key is used.
			 * @since 1.15.0
			 */
			selectedKey : {type : "string", group : "Data", defaultValue : null},

			/**
			 * Specifies whether the control is rendered.
			 * @since 1.15.0
			 */
			visible : {type : "boolean", group : "Behavior", defaultValue : true},

			/**
			 * Specifies the header mode.
			 * <b>Note:</b> The Inline mode works only if no icons are set.
			 *
			 * @since 1.40
			 */
			mode : {type : "sap.m.IconTabHeaderMode", group : "Appearance", defaultValue : sap.m.IconTabHeaderMode.Standard},

			/**
			 * Specifies if the overflow select list is displayed.
			 *
			 * The overflow select list represents a list, where all tab filters are displayed,
			 * so the user can select specific tab filter easier.
			 * @since 1.42
			 */
			showOverflowSelectList : {type : "boolean", group : "Appearance", defaultValue : false},

			/**
			 * Specifies the background color of the header.
			 *
			 * Depending on the theme, you can change the state of
			 * the background color to "Solid", "Translucent", or "Transparent".
			 * Default is "Solid".
			 * @since 1.44
			 */
			backgroundDesign : {type : "sap.m.BackgroundDesign", group : "Appearance", defaultValue : sap.m.BackgroundDesign.Solid},

			/**
			 * Specifies whether tab reordering is enabled. Relevant only for desktop devices.
			 * @since 1.46
			 */
			enableTabReordering : {type : "boolean", group : "Behavior", defaultValue : false}
		},
		aggregations : {

			/**
			 * The items displayed in the IconTabHeader.
			 */
			items : {type : "sap.m.IconTab", multiple : true, singularName : "item"}
		},
		events : {

			/**
			 * Fires when an item is selected.
			 */
			select : {
				parameters : {

					/**
					 * The selected item
					 * @since 1.15.0
					 */
					item : {type : "sap.m.IconTabFilter"},

					/**
					 * The key of the selected item
					 * @since 1.15.0
					 */
					key : {type : "string"}
				}
			}
		}
	}});

	EnabledPropagator.apply(IconTabHeader.prototype, [true]);

	IconTabHeader.ANIMATION_DURATION = sap.ui.getCore().getConfiguration().getAnimation() ? 200 : 0;
	IconTabHeader.SCROLL_STEP = 264; // how many pixels to scroll with every overflow arrow click

	IconTabHeader.prototype.init = function() {
		this._bPreviousScrollForward = false; // remember the item overflow state
		this._bPreviousScrollBack = false;
		this._iCurrentScrollLeft = 0;
		this._bRtl = sap.ui.getCore().getConfiguration().getRTL();

		this.startScrollX = 0;
		this.startTouchX = 0;
		this._scrollable = null;

		this._aTabKeys = [];

		// Initialize the ItemNavigation
		this._oItemNavigation = new ItemNavigation().setCycling(false);
		this._oItemNavigation.attachEvent(ItemNavigation.Events.FocusLeave, this._onItemNavigationFocusLeave, this);
		this._oItemNavigation.attachEvent(ItemNavigation.Events.AfterFocus, this._onItemNavigationAfterFocus, this);
		this.addDelegate(this._oItemNavigation);

		this._oScroller = new ScrollEnablement(this, this.getId() + "-head", {
			horizontal: true,
			vertical: false,
			nonTouchScrolling: true
		});
	};

	/**
	 * Returns overflow select list
	 * @private
	 */
	IconTabHeader.prototype._getSelectList = function () {

		var that = this;

		if (!this._oSelectList) {
			this._oSelectList = new IconTabBarSelectList({
				selectionChange: function (oEvent) {
					var oTarget = oEvent.getParameter('selectedItem');
					that.setSelectedItem(oTarget._tabFilter);
				}
			});

			this._oSelectList._iconTabHeader = this;
		}

		return this._oSelectList;
	};

	/**
	 * Returns overflow button
	 * @private
	 */
	IconTabHeader.prototype._getOverflowButton = function () {
		if (!this._oOverflowButton) {
			this._oOverflowButton = new Button({
				id: this.getId() + '-overflow',
				icon: "sap-icon://overflow",
				type: sap.m.ButtonType.Transparent,
				press: this._overflowButtonPress.bind(this)
			});
		}

		return this._oOverflowButton;
	};

	/**
	 * Handles overrflow button "press" event
	 * @private
	 */
	IconTabHeader.prototype._overflowButtonPress = function (event) {

		if (!this._oPopover) {
			this._oPopover = new ResponsivePopover({
					showArrow: false,
					showHeader: false,
					placement: sap.m.PlacementType.Vertical,
					offsetX: 0,
					offsetY: 0
				}
			).addStyleClass('sapMITBPopover');

			if (sap.ui.Device.system.phone) {
				this._oPopover._oControl.addButton(this._createPopoverCloseButton());
			}
		}

		var oSelectList = this._getSelectList();
		this._setSelectListItems();

		this._oPopover.removeAllContent();
		this._oPopover.addContent(oSelectList);

		this._oPopover.setInitialFocus(oSelectList.getSelectedItem());

		this._oPopover.openBy(this._getOverflowButton());
	};

	/**
	 * Creates popover close button
	 * @private
	 */
	IconTabHeader.prototype._createPopoverCloseButton = function() {
		var that = this;
		var oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.m");
		return new Button({
			text: oResourceBundle.getText("SELECT_CANCEL_BUTTON"),
			press: function() {
				that._closeOverflow();
			}
		});
	};

	/**
	 * Closes the overflow popover and focuses the correct tab filter
	 * @private
	 */
	IconTabHeader.prototype._closeOverflow = function () {

		if (!sap.ui.Device.system.desktop) {
			this._oPopover.close();
		}

		if (this.oSelectedItem) {
			this.oSelectedItem.$().focus();
		}
	};

	/**
	 * Sets overflow items
	 *
	 * @returns {sap.ui.core.Element}
	 * @private
	 */
	IconTabHeader.prototype._setSelectListItems = function () {

		if (!this.getShowOverflowSelectList()) {
			return;
		}

		var oSelectItem,
			oTabFilter,
			oSelectList = this._getSelectList(),
			aTabFilters = this.getTabFilters();

		oSelectList.removeAllItems();

		for (var i = 0; i < aTabFilters.length; i++) {
			oTabFilter = aTabFilters[i];

			oSelectItem = oTabFilter.clone();
			oSelectItem._tabFilter = oTabFilter;
			oSelectList.addItem(oSelectItem);

			if (oTabFilter == this.oSelectedItem) {
				oSelectList.setSelectedItem(oSelectItem);
			}
		}
	};

	/**
	 * Returns SelectList item, that corresponds ot specific TabFilter.
	 * @private
	 */
	IconTabHeader.prototype._findSelectItem = function (oTabFilter) {

		var oSelectList = this._getSelectList(),
			aSelectListItems = oSelectList.getItems(),
			oSelectItem;

		for (var i = 0; i < aSelectListItems.length; i++){

			oSelectItem = aSelectListItems[i];

			if (oSelectItem._tabFilter == oTabFilter) {
				return oSelectItem;
			}
		}
	};

	IconTabHeader.prototype._onItemNavigationFocusLeave = function() {

		// BCP: 1570034646
		if (!this.oSelectedItem) {
			return;
		}

		var aItems = this.getItems();
		var iIndex = -1;
		var oItem;

		for (var i = 0; i < aItems.length; i++) {
			oItem = aItems[i];

			if (oItem instanceof sap.m.IconTabFilter == false) {
				continue;
			}

			iIndex++;

			if (this.oSelectedItem == oItem) {
				break;
			}
		}

		this._oItemNavigation.setFocusedIndex(iIndex);
	};

	/**
	 * Adjusts arrows when keyboard is used for navigation and the beginning/end of the toolbar is reached.
	 * @private
	 */
	IconTabHeader.prototype._onItemNavigationAfterFocus = function(oEvent) {
		var oHead = this.getDomRef("head"),
			oIndex = oEvent.getParameter("index"),
			$event = oEvent.getParameter('event');

		// handle only keyboard navigation here
		if ($event.keyCode === undefined) {
			return;
		}

		this._iCurrentScrollLeft = oHead.scrollLeft;

		this._checkOverflow();

		if (oIndex !== null && oIndex !== undefined) {
			this._scrollIntoView(this.getTabFilters()[oIndex], 0);
		}
	};

	/**
	 * Returns all tab filters, without the tab separators.
	 * @private
	 */
	IconTabHeader.prototype.getTabFilters = function() {

		var aItems = this.getItems();
		var aTabFilters = [];

		aItems.forEach(function(oItem) {
			if (oItem instanceof sap.m.IconTabFilter) {
				aTabFilters.push(oItem);
			}
		});

		return aTabFilters;
	};

	IconTabHeader.prototype.exit = function() {
		if (this._oArrowLeft) {
			this._oArrowLeft.destroy();
		}
		if (this._oArrowRight) {
			this._oArrowRight.destroy();
		}

		if (this._oItemNavigation) {
			this.removeDelegate(this._oItemNavigation);
			this._oItemNavigation.destroy();
			delete this._oItemNavigation;
		}

		if (this._oScroller) {
			this._oScroller.destroy();
			this._oScroller = null;
		}

		if (this._sResizeListenerId) {
			sap.ui.core.ResizeHandler.deregister(this._sResizeListenerId);
			this._sResizeListenerId = null;
		}
		if (this._aTabKeys) {
			this._aTabKeys = null;
		}

		if (this._oPopover) {
			this._oPopover.destroy();
			this._oPopover = null;
		}

		if (this._oOverflowButton) {
			this._oOverflowButton.destroy();
			this._oOverflowButton = null;
		}
	};

	IconTabHeader.prototype.onBeforeRendering = function() {
		var aItems = this.getItems(),
			sSelectedKey = this.getSelectedKey(),
			i = 0;

		if (this._sResizeListenerId) {
			sap.ui.core.ResizeHandler.deregister(this._sResizeListenerId);
			this._sResizeListenerId = null;
		}

		if (aItems.length > 0) {
			if (!this.oSelectedItem || sSelectedKey && sSelectedKey !== this.oSelectedItem._getNonEmptyKey()) {
				if (sSelectedKey) {
					// selected key was specified by API: set oSelectedItem to the item specified by key
					for (; i < aItems.length; i++) {
						if (!(aItems[i] instanceof sap.m.IconTabSeparator) && aItems[i]._getNonEmptyKey() === sSelectedKey) {
							this.oSelectedItem = aItems[i];
							break;
						}
					}
				}

				// no key and no item, we set the first visible item as selected
				if (!this.oSelectedItem) {
					for (i = 0; i < aItems.length; i++) { // tab item
						if (!(aItems[i] instanceof sap.m.IconTabSeparator) && aItems[i].getVisible()) {
							this.oSelectedItem = aItems[i];
							break;
						}
					}
				}
			}

			//in case the selected tab is not visible anymore, the selected tab will change to the first visible tab
			if (this.oSelectedItem && !this.oSelectedItem.getVisible()) {
				for (i = 0; i < aItems.length; i++) { // tab item
					if (!(aItems[i] instanceof sap.m.IconTabSeparator) && aItems[i].getVisible()) {
						this.oSelectedItem = aItems[i];
						break;
					}
				}
			}

			if (this.oSelectedItem) {
				this.setProperty("selectedKey", this.oSelectedItem._getNonEmptyKey(), true);
			}
		}

		// Deregister resize event before re-rendering
		if (this._sResizeListenerNoFlexboxSupportId) {
			sap.ui.core.ResizeHandler.deregister(this._sResizeListenerNoFlexboxSupportId);
			this._sResizeListenerNoFlexboxSupportId = null;
		}
	};

	/**
	 * Sets the selected item based on key.
	 * @overwrite
	 * @public
	 * @param {string} sKey The key of the item to be selected
	 * @return {sap.m.IconTabHeader} this pointer for chaining
	 */
	IconTabHeader.prototype.setSelectedKey = function (sKey) {
		var aItems = this.getTabFilters(),
			i = 0;

		if (aItems.length > 0) {
			sKey = sKey || aItems[0]._getNonEmptyKey();
		}

		// adjust UI and internal variables if already rendered (otherwise taken care by onBeforeRendering)
		if (this.$().length) {
			for (; i < aItems.length; i++) {
				if (aItems[i]._getNonEmptyKey() === sKey) {
					this.setSelectedItem(aItems[i], true);
					break;
				}
			}
		}

		// set internal property
		this.setProperty("selectedKey", sKey, true);
		return this;
	};

	/*
	 * Sets the selected item, updates the UI, and fires the select event.
	 * @private
	 * @param {sap.m.IconTabFilter} oItem The item to be selected
	 * @param {Boolean} bAPIChange whether this function is called through the API
	 * @return {sap.m.IconTabHeader} this pointer for chaining
	 */
	IconTabHeader.prototype.setSelectedItem = function(oItem, bAPIchange) {

		if (!oItem || !oItem.getEnabled()) {
			return this;
		}

		if (this.getShowOverflowSelectList()) {
			var oSelectItem = this._findSelectItem(oItem);
			if (oSelectItem) {
				this._getSelectList().setSelectedItem(oSelectItem);
			}
		}

		var oParent = this.getParent();
		var bIsParentIconTabBar = oParent instanceof sap.m.IconTabBar;

		//if the old selected tab and the new selected tab both have no own content, which means they both use the same content from the icontabbar
		//there is no need to rerender the content
		//fix for xml views css: 0120061532 0001427250 2014
		var bIsContentTheSame = false;
		if (oItem.getContent().length === 0  && this.oSelectedItem && this.oSelectedItem.getContent().length === 0) {
			bIsContentTheSame = true;
		}

		if (this.oSelectedItem &&
			this.oSelectedItem.getVisible() &&
			(bIsParentIconTabBar && oParent.getExpandable() || this.oSelectedItem !== oItem)) {
			this.oSelectedItem.$()
					.removeClass("sapMITBSelected")
					.attr('aria-selected', false)
					.removeAttr('aria-expanded');
		}

		if (oItem.getVisible()) {
			//click on already selected item leads to expanding/collapsing of the content (if expandable enabled)
			if (this.oSelectedItem === oItem) {
				//if content is not expandable nothing should happen otherwise content will be expanded/collapsed
				if (!bAPIchange && bIsParentIconTabBar && oParent.getExpandable()) {
					oParent._toggleExpandCollapse();
				}
			//click on other item leads to showing the right content of this item
			} else {
				//change the content aria-labaled by the newly selected tab;
				if (bIsParentIconTabBar) {
					oParent.$("content").attr('aria-labelledby', oItem.sId);
				}

				// set new item
				this.oSelectedItem = oItem;
				this.setProperty("selectedKey", this.oSelectedItem._getNonEmptyKey(), true);

				if (!bIsParentIconTabBar) {
					this.oSelectedItem.$()
						.addClass("sapMITBSelected")
						.attr({ 'aria-selected': true });
				}

				//if the IconTabBar is not expandable and the content not expanded (which means content can never be expanded), we do not need
				//to visualize the selection and we do not need to render the content
				if (bIsParentIconTabBar && (oParent.getExpandable() || oParent.getExpanded())) {
					// add selected styles
					this.oSelectedItem.$()
							.addClass("sapMITBSelected")
							.attr({ 'aria-selected': true });

					//if item has own content, this content is shown
					var oSelectedItemContent = this.oSelectedItem.getContent();
					if (oSelectedItemContent.length > 0) {
						oParent._rerenderContent(oSelectedItemContent);
					//if item has not own content, general content of the icontabbar is shown
					} else {
						//if the general content was already shown there is no need to rerender
						if (!bIsContentTheSame) {
							oParent._rerenderContent(oParent.getContent());
						}
					}
					//if content is not expanded, content will be expanded (first click on item always leads to expanding the right content)
					if (!bAPIchange && oParent.getExpandable() && !oParent.getExpanded()) {
						oParent._toggleExpandCollapse(true);
					}
				}
			}

			// scroll to item if out of viewport
			if (this.oSelectedItem.$().length > 0) {
				this._scrollIntoView(oItem, 500);
			} else {
				this._scrollAfterRendering = true;
			}
		}

		var sSelectedKey = this.oSelectedItem._getNonEmptyKey();
		this.oSelectedItem = oItem;
		this.setProperty("selectedKey", sSelectedKey, true);
		if (bIsParentIconTabBar) {
			oParent.setProperty("selectedKey", sSelectedKey, true);
		}

		if (!bAPIchange) {
			// fire event on iconTabBar
			if (bIsParentIconTabBar) {
				oParent.fireSelect({
					selectedItem: this.oSelectedItem,
					selectedKey: sSelectedKey,
					item: this.oSelectedItem,
					key: sSelectedKey
				});
			} else {
				// fire event on header
				this.fireSelect({
					selectedItem: this.oSelectedItem,
					selectedKey: sSelectedKey,
					item: this.oSelectedItem,
					key: sSelectedKey
				});
			}
		}
		return this;
	};

	/**
	 * Returns the first visible item, which is needed for correct arrow calculation.
	 */
	IconTabHeader.prototype._getFirstVisibleItem = function(aItems) {
		for (var i = 0; i < aItems.length; i++) {
			if (aItems[i].getVisible()) {
				return aItems[i];
			}
		}

		return null;
	};

	IconTabHeader.prototype._initItemNavigation = function() {
		//use ItemNavigation for keyboardHandling
		var that = this,
			oHeadDomRef = this.getDomRef("head"),
			aItems = this.getItems(),
			aTabDomRefs = [],
			iSelectedDomIndex = -1;

		// find a collection of all tabs
		aItems.forEach(function(oItem) {
			if (oItem instanceof sap.m.IconTabFilter) {
				var oItemDomRef = that.getFocusDomRef(oItem);
				jQuery(oItemDomRef).attr("tabindex", "-1");
				aTabDomRefs.push(oItemDomRef);
				if (oItem === that.oSelectedItem) {
					iSelectedDomIndex = aTabDomRefs.indexOf(oItemDomRef);
				}
			}
		});

		//Initialize the ItemNavigation
		if (!this._oItemNavigation) {
			this._oItemNavigation = new ItemNavigation();
			this._oItemNavigation.attachEvent(ItemNavigation.Events.FocusLeave, this._onItemNavigationFocusLeave, this);
			this._oItemNavigation.attachEvent(ItemNavigation.Events.AfterFocus, this._onItemNavigationAfterFocus, this);
			this.addDelegate(this._oItemNavigation);
		}

		//Reinitialize the ItemNavigation after rendering
		this._oItemNavigation.setRootDomRef(oHeadDomRef);
		this._oItemNavigation.setItemDomRefs(aTabDomRefs);
		this._oItemNavigation.setSelectedIndex(iSelectedDomIndex);
	};

	IconTabHeader.prototype.onAfterRendering = function() {
		// initialize scrolling
		if (this._oScroller) {
			this._oScroller.setIconTabBar(this, jQuery.proxy(this._afterIscroll, this), jQuery.proxy(this._scrollPreparation, this));
		}

		var oParent = this.getParent();
		var bIsParentIconTabBar = oParent instanceof sap.m.IconTabBar;

		if (this.oSelectedItem &&
			(!bIsParentIconTabBar || bIsParentIconTabBar && oParent.getExpanded())) {
			this.oSelectedItem.$()
					.addClass("sapMITBSelected")
					.attr({ 'aria-selected': true });
		}

		jQuery.sap.delayedCall(350, this, "_checkOverflow");

		// scroll to selected item if it is out of screen and we render the control the first time
		if (this.oSelectedItem) {
			if (!this._bDoThisOnlyOnce) {
				jQuery.sap.delayedCall(1000, this, "_scrollIntoView", [this.oSelectedItem, 0]); // needs some delay to have correct position info
				this._bDoThisOnlyOnce = true;
			} else if (this._scrollAfterRendering) {
				this._scrollIntoView(this.oSelectedItem, 500);
				this._scrollAfterRendering = false;
			}
		}

		this._initItemNavigation();

		// overflow button doesn't have tab stop
		if (this.getShowOverflowSelectList()) {
			this.$('overflow').attr('tabindex', -1);
		}

		//listen to resize
		this._sResizeListenerId = sap.ui.core.ResizeHandler.register(this.getDomRef(),  jQuery.proxy(this._fnResize, this));

		// Change ITB content height on resize when ITB stretchContentHeight is set to true (IE9 fix)
		if (!jQuery.support.newFlexBoxLayout &&
			bIsParentIconTabBar &&
			oParent.getStretchContentHeight()) {
			this._sResizeListenerNoFlexboxSupportId = sap.ui.core.ResizeHandler.register(oParent.getDomRef(), jQuery.proxy(this._fnResizeNoFlexboxSupport, this));
			this._fnResizeNoFlexboxSupport();
		}

	};

	/*
	 * Destroys the item aggregation.
	 */
	IconTabHeader.prototype.destroyItems = function() {
		this.oSelectedItem = null;
		this._aTabKeys = [];
		this.destroyAggregation("items");
	};

	IconTabHeader.prototype.addItem = function(oItem) {
		if (!(oItem instanceof sap.m.IconTabSeparator)) {
			var sKey = oItem.getKey();
			// check if key is a duplicate
			if (this._aTabKeys.indexOf(sKey) !== -1) {
				jQuery.sap.log.warning("sap.m.IconTabHeader: duplicate key '" + sKey + "' inside the IconTabFilter. Please use unique keys.");
			}
			this._aTabKeys.push(sKey);
		}
		this.addAggregation("items", oItem);
	};

	IconTabHeader.prototype.insertItem = function(oItem, iIndex) {
		if (!(oItem instanceof sap.m.IconTabSeparator)) {
			var sKey = oItem.getKey();
			//check if key is a duplicate
			if (this._aTabKeys.indexOf(sKey) !== -1) {
				jQuery.sap.log.warning("sap.m.IconTabHeader: duplicate key '" + sKey + "' inside the IconTabFilter. Please use unique keys.");
			}
			this._aTabKeys.push(sKey);
		}
		this.insertAggregation("items", oItem, iIndex);
	};

	IconTabHeader.prototype.removeAllItems = function() {
		this._aTabKeys = [];
		this.removeAllAggregation("items");
	};

	IconTabHeader.prototype.removeItem = function(oItem) {
		// Make sure we have the actual Item and not just an ID
		oItem = this.removeAggregation("items", oItem);

		if (oItem && !(oItem instanceof sap.m.IconTabSeparator)) {
			var sKey = oItem.getKey();
			this._aTabKeys.splice(this._aTabKeys.indexOf(sKey) , 1);
		}

		// Return the original value from removeAggregation
		return oItem;
	};

	IconTabHeader.prototype.removeAggregation = function (sAggregationName, oObject, bSuppressInvalidate) {

		var aItems = this.getTabFilters();

		var oItem = Control.prototype.removeAggregation.apply(this, arguments);

		// don't change selected item while drag-drop
		if (this._oDragContext) {
			return oItem;
		}

		if (oItem && oItem == this.oSelectedItem && sAggregationName == 'items') {

			var iIndexOf = jQuery.inArray(oItem, aItems);
			aItems = this.getTabFilters();

			iIndexOf = Math.max(0, Math.min(iIndexOf, aItems.length - 1));

			var oSelectedItem = aItems[iIndexOf];

			if (oSelectedItem) {
				this.setSelectedItem(oSelectedItem);
			} else {
				var oIconTabBar = this.getParent();
				if (oIconTabBar instanceof sap.m.IconTabBar && oIconTabBar.getExpanded()) {
					oIconTabBar.$("content").children().remove();
				}
			}
		}

		return oItem;
	};

	IconTabHeader.prototype.removeAllAggregation = function (sAggregationName, bSuppressInvalidate) {

		if (sAggregationName == 'items') {
			var oIconTabBar = this.getParent();
			if (oIconTabBar instanceof sap.m.IconTabBar && oIconTabBar.getExpanded()) {
				oIconTabBar.$("content").children().remove();
			}
		}

		return Control.prototype.removeAllAggregation.apply(this, arguments);
	};

	/**
	 * Returns the displayed text - text or text + (count)
	 * @private
	 */
	IconTabHeader.prototype._getDisplayText = function (oItem) {
		var sText = oItem.getText();

		if (this.isInlineMode()) {<commit_msg>[FIX] sap.m.IconTabBar: "select" event is not fired any more when control is destroyed<commit_after>/*!
 * ${copyright}
 */

// Provides control sap.m.IconTabHeader.
sap.ui.define(['jquery.sap.global', './library', 'sap/ui/core/Control', 'sap/ui/core/EnabledPropagator',
		'sap/ui/core/delegate/ItemNavigation', 'sap/ui/core/IconPool', 'sap/ui/core/delegate/ScrollEnablement',
		'./IconTabBarSelectList', './Button', './ResponsivePopover', './IconTabFilter'],
	function(jQuery, library, Control, EnabledPropagator,
				ItemNavigation, IconPool, ScrollEnablement,
				IconTabBarSelectList, Button, ResponsivePopover, IconTabFilter) {
	"use strict";

	/**
	 * Constructor for a new IconTabHeader.
	 *
	 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
	 * @param {object} [mSettings] Initial settings for the new control
	 *
	 * @class
	 * This control displays a number of IconTabFilters and IconTabSeparators. If the available horizontal
	 * space is exceeded, a horizontal scrolling appears.
	 * @extends sap.ui.core.Control
	 *
	 * @author SAP SE
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @alias sap.m.IconTabHeader
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var IconTabHeader = Control.extend("sap.m.IconTabHeader", /** @lends sap.m.IconTabHeader.prototype */ { metadata : {

		library : "sap.m",
		properties : {

			/**
			 * Defines whether the current selection is visualized.
			 * @deprecated As of 1.15.0.
			 * Regarding to changes of this control this property is not needed anymore.
			 */
			showSelection : {type : "boolean", group : "Misc", defaultValue : true, deprecated: true},

			/**
			 * Key of the selected item.
			 *
			 * If the key has no corresponding aggregated item, no changes will apply.
			 * If duplicate keys exists the first item matching, the key is used.
			 * @since 1.15.0
			 */
			selectedKey : {type : "string", group : "Data", defaultValue : null},

			/**
			 * Specifies whether the control is rendered.
			 * @since 1.15.0
			 */
			visible : {type : "boolean", group : "Behavior", defaultValue : true},

			/**
			 * Specifies the header mode.
			 * <b>Note:</b> The Inline mode works only if no icons are set.
			 *
			 * @since 1.40
			 */
			mode : {type : "sap.m.IconTabHeaderMode", group : "Appearance", defaultValue : sap.m.IconTabHeaderMode.Standard},

			/**
			 * Specifies if the overflow select list is displayed.
			 *
			 * The overflow select list represents a list, where all tab filters are displayed,
			 * so the user can select specific tab filter easier.
			 * @since 1.42
			 */
			showOverflowSelectList : {type : "boolean", group : "Appearance", defaultValue : false},

			/**
			 * Specifies the background color of the header.
			 *
			 * Depending on the theme, you can change the state of
			 * the background color to "Solid", "Translucent", or "Transparent".
			 * Default is "Solid".
			 * @since 1.44
			 */
			backgroundDesign : {type : "sap.m.BackgroundDesign", group : "Appearance", defaultValue : sap.m.BackgroundDesign.Solid},

			/**
			 * Specifies whether tab reordering is enabled. Relevant only for desktop devices.
			 * @since 1.46
			 */
			enableTabReordering : {type : "boolean", group : "Behavior", defaultValue : false}
		},
		aggregations : {

			/**
			 * The items displayed in the IconTabHeader.
			 */
			items : {type : "sap.m.IconTab", multiple : true, singularName : "item"}
		},
		events : {

			/**
			 * Fires when an item is selected.
			 */
			select : {
				parameters : {

					/**
					 * The selected item
					 * @since 1.15.0
					 */
					item : {type : "sap.m.IconTabFilter"},

					/**
					 * The key of the selected item
					 * @since 1.15.0
					 */
					key : {type : "string"}
				}
			}
		}
	}});

	EnabledPropagator.apply(IconTabHeader.prototype, [true]);

	IconTabHeader.ANIMATION_DURATION = sap.ui.getCore().getConfiguration().getAnimation() ? 200 : 0;
	IconTabHeader.SCROLL_STEP = 264; // how many pixels to scroll with every overflow arrow click

	IconTabHeader.prototype.init = function() {
		this._bPreviousScrollForward = false; // remember the item overflow state
		this._bPreviousScrollBack = false;
		this._iCurrentScrollLeft = 0;
		this._bRtl = sap.ui.getCore().getConfiguration().getRTL();

		this.startScrollX = 0;
		this.startTouchX = 0;
		this._scrollable = null;

		this._aTabKeys = [];

		// Initialize the ItemNavigation
		this._oItemNavigation = new ItemNavigation().setCycling(false);
		this._oItemNavigation.attachEvent(ItemNavigation.Events.FocusLeave, this._onItemNavigationFocusLeave, this);
		this._oItemNavigation.attachEvent(ItemNavigation.Events.AfterFocus, this._onItemNavigationAfterFocus, this);
		this.addDelegate(this._oItemNavigation);

		this._oScroller = new ScrollEnablement(this, this.getId() + "-head", {
			horizontal: true,
			vertical: false,
			nonTouchScrolling: true
		});
	};

	/**
	 * Returns overflow select list
	 * @private
	 */
	IconTabHeader.prototype._getSelectList = function () {

		var that = this;

		if (!this._oSelectList) {
			this._oSelectList = new IconTabBarSelectList({
				selectionChange: function (oEvent) {
					var oTarget = oEvent.getParameter('selectedItem');
					that.setSelectedItem(oTarget._tabFilter);
				}
			});

			this._oSelectList._iconTabHeader = this;
		}

		return this._oSelectList;
	};

	/**
	 * Returns overflow button
	 * @private
	 */
	IconTabHeader.prototype._getOverflowButton = function () {
		if (!this._oOverflowButton) {
			this._oOverflowButton = new Button({
				id: this.getId() + '-overflow',
				icon: "sap-icon://overflow",
				type: sap.m.ButtonType.Transparent,
				press: this._overflowButtonPress.bind(this)
			});
		}

		return this._oOverflowButton;
	};

	/**
	 * Handles overrflow button "press" event
	 * @private
	 */
	IconTabHeader.prototype._overflowButtonPress = function (event) {

		if (!this._oPopover) {
			this._oPopover = new ResponsivePopover({
					showArrow: false,
					showHeader: false,
					placement: sap.m.PlacementType.Vertical,
					offsetX: 0,
					offsetY: 0
				}
			).addStyleClass('sapMITBPopover');

			if (sap.ui.Device.system.phone) {
				this._oPopover._oControl.addButton(this._createPopoverCloseButton());
			}
		}

		var oSelectList = this._getSelectList();
		this._setSelectListItems();

		this._oPopover.removeAllContent();
		this._oPopover.addContent(oSelectList);

		this._oPopover.setInitialFocus(oSelectList.getSelectedItem());

		this._oPopover.openBy(this._getOverflowButton());
	};

	/**
	 * Creates popover close button
	 * @private
	 */
	IconTabHeader.prototype._createPopoverCloseButton = function() {
		var that = this;
		var oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.m");
		return new Button({
			text: oResourceBundle.getText("SELECT_CANCEL_BUTTON"),
			press: function() {
				that._closeOverflow();
			}
		});
	};

	/**
	 * Closes the overflow popover and focuses the correct tab filter
	 * @private
	 */
	IconTabHeader.prototype._closeOverflow = function () {

		if (!sap.ui.Device.system.desktop) {
			this._oPopover.close();
		}

		if (this.oSelectedItem) {
			this.oSelectedItem.$().focus();
		}
	};

	/**
	 * Sets overflow items
	 *
	 * @returns {sap.ui.core.Element}
	 * @private
	 */
	IconTabHeader.prototype._setSelectListItems = function () {

		if (!this.getShowOverflowSelectList()) {
			return;
		}

		var oSelectItem,
			oTabFilter,
			oSelectList = this._getSelectList(),
			aTabFilters = this.getTabFilters();

		oSelectList.removeAllItems();

		for (var i = 0; i < aTabFilters.length; i++) {
			oTabFilter = aTabFilters[i];

			oSelectItem = oTabFilter.clone();
			oSelectItem._tabFilter = oTabFilter;
			oSelectList.addItem(oSelectItem);

			if (oTabFilter == this.oSelectedItem) {
				oSelectList.setSelectedItem(oSelectItem);
			}
		}
	};

	/**
	 * Returns SelectList item, that corresponds ot specific TabFilter.
	 * @private
	 */
	IconTabHeader.prototype._findSelectItem = function (oTabFilter) {

		var oSelectList = this._getSelectList(),
			aSelectListItems = oSelectList.getItems(),
			oSelectItem;

		for (var i = 0; i < aSelectListItems.length; i++){

			oSelectItem = aSelectListItems[i];

			if (oSelectItem._tabFilter == oTabFilter) {
				return oSelectItem;
			}
		}
	};

	IconTabHeader.prototype._onItemNavigationFocusLeave = function() {

		// BCP: 1570034646
		if (!this.oSelectedItem) {
			return;
		}

		var aItems = this.getItems();
		var iIndex = -1;
		var oItem;

		for (var i = 0; i < aItems.length; i++) {
			oItem = aItems[i];

			if (oItem instanceof sap.m.IconTabFilter == false) {
				continue;
			}

			iIndex++;

			if (this.oSelectedItem == oItem) {
				break;
			}
		}

		this._oItemNavigation.setFocusedIndex(iIndex);
	};

	/**
	 * Adjusts arrows when keyboard is used for navigation and the beginning/end of the toolbar is reached.
	 * @private
	 */
	IconTabHeader.prototype._onItemNavigationAfterFocus = function(oEvent) {
		var oHead = this.getDomRef("head"),
			oIndex = oEvent.getParameter("index"),
			$event = oEvent.getParameter('event');

		// handle only keyboard navigation here
		if ($event.keyCode === undefined) {
			return;
		}

		this._iCurrentScrollLeft = oHead.scrollLeft;

		this._checkOverflow();

		if (oIndex !== null && oIndex !== undefined) {
			this._scrollIntoView(this.getTabFilters()[oIndex], 0);
		}
	};

	/**
	 * Returns all tab filters, without the tab separators.
	 * @private
	 */
	IconTabHeader.prototype.getTabFilters = function() {

		var aItems = this.getItems();
		var aTabFilters = [];

		aItems.forEach(function(oItem) {
			if (oItem instanceof sap.m.IconTabFilter) {
				aTabFilters.push(oItem);
			}
		});

		return aTabFilters;
	};

	IconTabHeader.prototype.exit = function() {
		if (this._oArrowLeft) {
			this._oArrowLeft.destroy();
		}
		if (this._oArrowRight) {
			this._oArrowRight.destroy();
		}

		if (this._oItemNavigation) {
			this.removeDelegate(this._oItemNavigation);
			this._oItemNavigation.destroy();
			delete this._oItemNavigation;
		}

		if (this._oScroller) {
			this._oScroller.destroy();
			this._oScroller = null;
		}

		if (this._sResizeListenerId) {
			sap.ui.core.ResizeHandler.deregister(this._sResizeListenerId);
			this._sResizeListenerId = null;
		}
		if (this._aTabKeys) {
			this._aTabKeys = null;
		}

		if (this._oPopover) {
			this._oPopover.destroy();
			this._oPopover = null;
		}

		if (this._oOverflowButton) {
			this._oOverflowButton.destroy();
			this._oOverflowButton = null;
		}
	};

	IconTabHeader.prototype.onBeforeRendering = function() {
		var aItems = this.getItems(),
			sSelectedKey = this.getSelectedKey(),
			i = 0;

		if (this._sResizeListenerId) {
			sap.ui.core.ResizeHandler.deregister(this._sResizeListenerId);
			this._sResizeListenerId = null;
		}

		if (aItems.length > 0) {
			if (!this.oSelectedItem || sSelectedKey && sSelectedKey !== this.oSelectedItem._getNonEmptyKey()) {
				if (sSelectedKey) {
					// selected key was specified by API: set oSelectedItem to the item specified by key
					for (; i < aItems.length; i++) {
						if (!(aItems[i] instanceof sap.m.IconTabSeparator) && aItems[i]._getNonEmptyKey() === sSelectedKey) {
							this.oSelectedItem = aItems[i];
							break;
						}
					}
				}

				// no key and no item, we set the first visible item as selected
				if (!this.oSelectedItem) {
					for (i = 0; i < aItems.length; i++) { // tab item
						if (!(aItems[i] instanceof sap.m.IconTabSeparator) && aItems[i].getVisible()) {
							this.oSelectedItem = aItems[i];
							break;
						}
					}
				}
			}

			//in case the selected tab is not visible anymore, the selected tab will change to the first visible tab
			if (this.oSelectedItem && !this.oSelectedItem.getVisible()) {
				for (i = 0; i < aItems.length; i++) { // tab item
					if (!(aItems[i] instanceof sap.m.IconTabSeparator) && aItems[i].getVisible()) {
						this.oSelectedItem = aItems[i];
						break;
					}
				}
			}

			if (this.oSelectedItem) {
				this.setProperty("selectedKey", this.oSelectedItem._getNonEmptyKey(), true);
			}
		}

		// Deregister resize event before re-rendering
		if (this._sResizeListenerNoFlexboxSupportId) {
			sap.ui.core.ResizeHandler.deregister(this._sResizeListenerNoFlexboxSupportId);
			this._sResizeListenerNoFlexboxSupportId = null;
		}
	};

	/**
	 * Sets the selected item based on key.
	 * @overwrite
	 * @public
	 * @param {string} sKey The key of the item to be selected
	 * @return {sap.m.IconTabHeader} this pointer for chaining
	 */
	IconTabHeader.prototype.setSelectedKey = function (sKey) {
		var aItems = this.getTabFilters(),
			i = 0;

		if (aItems.length > 0) {
			sKey = sKey || aItems[0]._getNonEmptyKey();
		}

		// adjust UI and internal variables if already rendered (otherwise taken care by onBeforeRendering)
		if (this.$().length) {
			for (; i < aItems.length; i++) {
				if (aItems[i]._getNonEmptyKey() === sKey) {
					this.setSelectedItem(aItems[i], true);
					break;
				}
			}
		}

		// set internal property
		this.setProperty("selectedKey", sKey, true);
		return this;
	};

	/*
	 * Sets the selected item, updates the UI, and fires the select event.
	 * @private
	 * @param {sap.m.IconTabFilter} oItem The item to be selected
	 * @param {Boolean} bAPIChange whether this function is called through the API
	 * @return {sap.m.IconTabHeader} this pointer for chaining
	 */
	IconTabHeader.prototype.setSelectedItem = function(oItem, bAPIchange) {

		if (!oItem || !oItem.getEnabled()) {
			return this;
		}

		if (this.getShowOverflowSelectList()) {
			var oSelectItem = this._findSelectItem(oItem);
			if (oSelectItem) {
				this._getSelectList().setSelectedItem(oSelectItem);
			}
		}

		var oParent = this.getParent();
		var bIsParentIconTabBar = oParent instanceof sap.m.IconTabBar;

		//if the old selected tab and the new selected tab both have no own content, which means they both use the same content from the icontabbar
		//there is no need to rerender the content
		//fix for xml views css: 0120061532 0001427250 2014
		var bIsContentTheSame = false;
		if (oItem.getContent().length === 0  && this.oSelectedItem && this.oSelectedItem.getContent().length === 0) {
			bIsContentTheSame = true;
		}

		if (this.oSelectedItem &&
			this.oSelectedItem.getVisible() &&
			(bIsParentIconTabBar && oParent.getExpandable() || this.oSelectedItem !== oItem)) {
			this.oSelectedItem.$()
					.removeClass("sapMITBSelected")
					.attr('aria-selected', false)
					.removeAttr('aria-expanded');
		}

		if (oItem.getVisible()) {
			//click on already selected item leads to expanding/collapsing of the content (if expandable enabled)
			if (this.oSelectedItem === oItem) {
				//if content is not expandable nothing should happen otherwise content will be expanded/collapsed
				if (!bAPIchange && bIsParentIconTabBar && oParent.getExpandable()) {
					oParent._toggleExpandCollapse();
				}
			//click on other item leads to showing the right content of this item
			} else {
				//change the content aria-labaled by the newly selected tab;
				if (bIsParentIconTabBar) {
					oParent.$("content").attr('aria-labelledby', oItem.sId);
				}

				// set new item
				this.oSelectedItem = oItem;
				this.setProperty("selectedKey", this.oSelectedItem._getNonEmptyKey(), true);

				if (!bIsParentIconTabBar) {
					this.oSelectedItem.$()
						.addClass("sapMITBSelected")
						.attr({ 'aria-selected': true });
				}

				//if the IconTabBar is not expandable and the content not expanded (which means content can never be expanded), we do not need
				//to visualize the selection and we do not need to render the content
				if (bIsParentIconTabBar && (oParent.getExpandable() || oParent.getExpanded())) {
					// add selected styles
					this.oSelectedItem.$()
							.addClass("sapMITBSelected")
							.attr({ 'aria-selected': true });

					//if item has own content, this content is shown
					var oSelectedItemContent = this.oSelectedItem.getContent();
					if (oSelectedItemContent.length > 0) {
						oParent._rerenderContent(oSelectedItemContent);
					//if item has not own content, general content of the icontabbar is shown
					} else {
						//if the general content was already shown there is no need to rerender
						if (!bIsContentTheSame) {
							oParent._rerenderContent(oParent.getContent());
						}
					}
					//if content is not expanded, content will be expanded (first click on item always leads to expanding the right content)
					if (!bAPIchange && oParent.getExpandable() && !oParent.getExpanded()) {
						oParent._toggleExpandCollapse(true);
					}
				}
			}

			// scroll to item if out of viewport
			if (this.oSelectedItem.$().length > 0) {
				this._scrollIntoView(oItem, 500);
			} else {
				this._scrollAfterRendering = true;
			}
		}

		var sSelectedKey = this.oSelectedItem._getNonEmptyKey();
		this.oSelectedItem = oItem;
		this.setProperty("selectedKey", sSelectedKey, true);
		if (bIsParentIconTabBar) {
			oParent.setProperty("selectedKey", sSelectedKey, true);
		}

		if (!bAPIchange) {
			// fire event on iconTabBar
			if (bIsParentIconTabBar) {
				oParent.fireSelect({
					selectedItem: this.oSelectedItem,
					selectedKey: sSelectedKey,
					item: this.oSelectedItem,
					key: sSelectedKey
				});
			} else {
				// fire event on header
				this.fireSelect({
					selectedItem: this.oSelectedItem,
					selectedKey: sSelectedKey,
					item: this.oSelectedItem,
					key: sSelectedKey
				});
			}
		}
		return this;
	};

	/**
	 * Returns the first visible item, which is needed for correct arrow calculation.
	 */
	IconTabHeader.prototype._getFirstVisibleItem = function(aItems) {
		for (var i = 0; i < aItems.length; i++) {
			if (aItems[i].getVisible()) {
				return aItems[i];
			}
		}

		return null;
	};

	IconTabHeader.prototype._initItemNavigation = function() {
		//use ItemNavigation for keyboardHandling
		var that = this,
			oHeadDomRef = this.getDomRef("head"),
			aItems = this.getItems(),
			aTabDomRefs = [],
			iSelectedDomIndex = -1;

		// find a collection of all tabs
		aItems.forEach(function(oItem) {
			if (oItem instanceof sap.m.IconTabFilter) {
				var oItemDomRef = that.getFocusDomRef(oItem);
				jQuery(oItemDomRef).attr("tabindex", "-1");
				aTabDomRefs.push(oItemDomRef);
				if (oItem === that.oSelectedItem) {
					iSelectedDomIndex = aTabDomRefs.indexOf(oItemDomRef);
				}
			}
		});

		//Initialize the ItemNavigation
		if (!this._oItemNavigation) {
			this._oItemNavigation = new ItemNavigation();
			this._oItemNavigation.attachEvent(ItemNavigation.Events.FocusLeave, this._onItemNavigationFocusLeave, this);
			this._oItemNavigation.attachEvent(ItemNavigation.Events.AfterFocus, this._onItemNavigationAfterFocus, this);
			this.addDelegate(this._oItemNavigation);
		}

		//Reinitialize the ItemNavigation after rendering
		this._oItemNavigation.setRootDomRef(oHeadDomRef);
		this._oItemNavigation.setItemDomRefs(aTabDomRefs);
		this._oItemNavigation.setSelectedIndex(iSelectedDomIndex);
	};

	IconTabHeader.prototype.onAfterRendering = function() {
		// initialize scrolling
		if (this._oScroller) {
			this._oScroller.setIconTabBar(this, jQuery.proxy(this._afterIscroll, this), jQuery.proxy(this._scrollPreparation, this));
		}

		var oParent = this.getParent();
		var bIsParentIconTabBar = oParent instanceof sap.m.IconTabBar;

		if (this.oSelectedItem &&
			(!bIsParentIconTabBar || bIsParentIconTabBar && oParent.getExpanded())) {
			this.oSelectedItem.$()
					.addClass("sapMITBSelected")
					.attr({ 'aria-selected': true });
		}

		jQuery.sap.delayedCall(350, this, "_checkOverflow");

		// scroll to selected item if it is out of screen and we render the control the first time
		if (this.oSelectedItem) {
			if (!this._bDoThisOnlyOnce) {
				jQuery.sap.delayedCall(1000, this, "_scrollIntoView", [this.oSelectedItem, 0]); // needs some delay to have correct position info
				this._bDoThisOnlyOnce = true;
			} else if (this._scrollAfterRendering) {
				this._scrollIntoView(this.oSelectedItem, 500);
				this._scrollAfterRendering = false;
			}
		}

		this._initItemNavigation();

		// overflow button doesn't have tab stop
		if (this.getShowOverflowSelectList()) {
			this.$('overflow').attr('tabindex', -1);
		}

		//listen to resize
		this._sResizeListenerId = sap.ui.core.ResizeHandler.register(this.getDomRef(),  jQuery.proxy(this._fnResize, this));

		// Change ITB content height on resize when ITB stretchContentHeight is set to true (IE9 fix)
		if (!jQuery.support.newFlexBoxLayout &&
			bIsParentIconTabBar &&
			oParent.getStretchContentHeight()) {
			this._sResizeListenerNoFlexboxSupportId = sap.ui.core.ResizeHandler.register(oParent.getDomRef(), jQuery.proxy(this._fnResizeNoFlexboxSupport, this));
			this._fnResizeNoFlexboxSupport();
		}

	};

	/*
	 * Destroys the item aggregation.
	 */
	IconTabHeader.prototype.destroyItems = function() {
		this.oSelectedItem = null;
		this._aTabKeys = [];
		this.destroyAggregation("items");
	};

	IconTabHeader.prototype.addItem = function(oItem) {
		if (!(oItem instanceof sap.m.IconTabSeparator)) {
			var sKey = oItem.getKey();
			// check if key is a duplicate
			if (this._aTabKeys.indexOf(sKey) !== -1) {
				jQuery.sap.log.warning("sap.m.IconTabHeader: duplicate key '" + sKey + "' inside the IconTabFilter. Please use unique keys.");
			}
			this._aTabKeys.push(sKey);
		}
		this.addAggregation("items", oItem);
	};

	IconTabHeader.prototype.insertItem = function(oItem, iIndex) {
		if (!(oItem instanceof sap.m.IconTabSeparator)) {
			var sKey = oItem.getKey();
			//check if key is a duplicate
			if (this._aTabKeys.indexOf(sKey) !== -1) {
				jQuery.sap.log.warning("sap.m.IconTabHeader: duplicate key '" + sKey + "' inside the IconTabFilter. Please use unique keys.");
			}
			this._aTabKeys.push(sKey);
		}
		this.insertAggregation("items", oItem, iIndex);
	};

	IconTabHeader.prototype.removeAllItems = function() {
		this._aTabKeys = [];
		this.removeAllAggregation("items");
	};

	IconTabHeader.prototype.removeItem = function(oItem) {
		// Make sure we have the actual Item and not just an ID
		oItem = this.removeAggregation("items", oItem);

		if (oItem && !(oItem instanceof sap.m.IconTabSeparator)) {
			var sKey = oItem.getKey();
			this._aTabKeys.splice(this._aTabKeys.indexOf(sKey) , 1);
		}

		// Return the original value from removeAggregation
		return oItem;
	};

	IconTabHeader.prototype.removeAggregation = function (sAggregationName, oObject, bSuppressInvalidate) {

		var aItems = this.getTabFilters();

		var oItem = Control.prototype.removeAggregation.apply(this, arguments);

		// don't change selected item while drag-drop
		if (this._oDragContext) {
			return oItem;
		}

		if (oItem && oItem == this.oSelectedItem && sAggregationName == 'items') {

			var iIndexOf = jQuery.inArray(oItem, aItems);
			aItems = this.getTabFilters();

			iIndexOf = Math.max(0, Math.min(iIndexOf, aItems.length - 1));

			var oSelectedItem = aItems[iIndexOf];

			if (oSelectedItem) {
				this.setSelectedItem(oSelectedItem, true);
			} else {
				var oIconTabBar = this.getParent();
				if (oIconTabBar instanceof sap.m.IconTabBar && oIconTabBar.getExpanded()) {
					oIconTabBar.$("content").children().remove();
				}
			}
		}

		return oItem;
	};

	IconTabHeader.prototype.removeAllAggregation = function (sAggregationName, bSuppressInvalidate) {

		if (sAggregationName == 'items') {
			var oIconTabBar = this.getParent();
			if (oIconTabBar instanceof sap.m.IconTabBar && oIconTabBar.getExpanded()) {
				oIconTabBar.$("content").children().remove();
			}
		}

		return Control.prototype.removeAllAggregation.apply(this, arguments);
	};

	/**
	 * Returns the displayed text - text or text + (count)
	 * @private
	 */
	IconTabHeader.prototype._getDisplayText = function (oItem) {
		var sText = oItem.getText();

		if (this.isInlineMode()) {
{'fraction_non_alphanumeric': 0.12634493173095074, 'fraction_numerical': 0.005033662618762977, 'mean_word_length': 3.483731427496709, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5433510', 'n_tokens_mistral': 17802, 'n_tokens_neox': 14942, 'n_words': 3545}