function(oTable) {
			if (!oTable.getEnableGrouping()) {
				return;
			}

			var oBinding = Element.prototype.getBinding.call(oTable, "rows");

			// check for grouping being supported or not (only for client ListBindings!!)
			var oGroupBy = sap.ui.getCore().byId(oTable.getGroupBy());
			var bIsSupported = oGroupBy && oGroupBy.getGrouped() && TableGrouping.TableUtils.isA(oBinding, "sap.ui.model.ClientListBinding");

			// only enhance the binding if it has not been done yet and supported!
			if (!bIsSupported || oBinding._modified) {
				return;
			}

			// once the binding is modified we always return the modified binding
			// and don't wanna modifiy the binding once again
			oBinding._modified = true;

			// set the table into grouping mode
			TableGrouping.setGroupMode(oTable);

			// we use sorting finally to sort the values and afterwards group them
			var sPropertyName = oGroupBy.getSortProperty();
			oBinding.sort(new Sorter(sPropertyName));

			// fetch the contexts from the original binding
			var iLength = oTable._getTotalRowCount(),
				aContexts = oBinding.getContexts(0, iLength);

			// add the context information for the group headers which are later on
			// used for displaying the grouping information of each group
			var sKey;
			var iCounter = 0;
			for (var i = iLength - 1; i >= 0; i--) {
				var sNewKey = aContexts[i].getProperty(sPropertyName);
				if (!sKey) {
					sKey = sNewKey;
				}
				if (sKey !== sNewKey) {
					var oGroupContext = aContexts[i + 1].getModel().getContext("/sap.ui.table.GroupInfo" + i);
					oGroupContext.__groupInfo = {
						oContext: aContexts[i + 1],
						name: sKey,
						count: iCounter,
						groupHeader: true,
						expanded: true
					};
					aContexts.splice(i + 1, 0,
						oGroupContext
					);
					sKey = sNewKey;
					iCounter = 0;
				}
				iCounter++;
			}
			var oGroupContext = aContexts[0].getModel().getContext("/sap.ui.table.GroupInfo");
			oGroupContext.__groupInfo = {
				oContext: aContexts[0],
				name: sKey,
				count: iCounter,
				groupHeader: true,
				expanded: true
			};
			aContexts.splice(0, 0, oGroupContext);

			// extend the binding and hook into the relevant functions to provide access to the grouping information
			// TODO: Unify this with the "look&feel" of the binding in the TreeTable --> _updateTableContent must only be implemented once
			jQuery.extend(oBinding, {
				getLength: function() {
					return aContexts.length;
				},
				getContexts: function(iStartIndex, iLength) {
					return aContexts.slice(iStartIndex, iStartIndex + iLength);
				},
				isGroupHeader: function(iIndex) {
					var oContext = aContexts[iIndex];
					return (oContext && oContext.__groupInfo && oContext.__groupInfo.groupHeader) === true;
				},
				getTitle: function(iIndex) {
					var oContext = aContexts[iIndex];
					return oContext && oContext.__groupInfo && oContext.__groupInfo.name + " - " + oContext.__groupInfo.count;
				},
				isExpanded: function(iIndex) {
					var oContext = aContexts[iIndex];
					return this.isGroupHeader(iIndex) && oContext.__groupInfo && oContext.__groupInfo.expanded;
				},
				expand: function(iIndex) {
					if (this.isGroupHeader(iIndex) && !aContexts[iIndex].__groupInfo.expanded) {
						for (var i = 0; i < aContexts[iIndex].__childs.length; i++) {
							aContexts.splice(iIndex + 1 + i, 0, aContexts[iIndex].__childs[i]);
						}
						delete aContexts[iIndex].__childs;
						aContexts[iIndex].__groupInfo.expanded = true;
						this._fireChange();
					}
				},
				collapse: function(iIndex) {
					if (this.isGroupHeader(iIndex) && aContexts[iIndex].__groupInfo.expanded) {
						aContexts[iIndex].__childs = aContexts.splice(iIndex + 1, aContexts[iIndex].__groupInfo.count);
						aContexts[iIndex].__groupInfo.expanded = false;
						this._fireChange();
					}
				},
				toggleIndex: function(iIndex) {
					if (this.isExpanded(iIndex)) {
						this.collapse(iIndex);
					} else {
						this.expand(iIndex);
					}
				},

				// For compatibility with TreeBinding adapters.
				nodeHasChildren: function(oContext) {
					if (!oContext || !oContext.__groupInfo) {
						return false;
					} else {
						return oContext.__groupInfo.groupHeader === true;
					}
				},
				getNodeByIndex: function(iIndex) {
					return aContexts[iIndex];
				}
			});

			// the table need to fetch the updated/changed contexts again, therefore requires the binding to fire a change event
			oTable._mTimeouts.groupingFireBindingChange = oTable._mTimeouts.groupingFireBindingChange || window.setTimeout(
				function() {oBinding._fireChange();}, 0);
		}
function(oTable) {
			if (!oTable.getEnableGrouping()) {
				return;
			}

			var oBinding = Element.prototype.getBinding.call(oTable, "rows");

			// check for grouping being supported or not (only for client ListBindings!!)
			var oGroupBy = sap.ui.getCore().byId(oTable.getGroupBy());
			var bIsSupported = oGroupBy && oGroupBy.getGrouped() && TableGrouping.TableUtils.isA(oBinding, "sap.ui.model.ClientListBinding");

			// only enhance the binding if it has not been done yet and supported!
			if (!bIsSupported || oBinding._modified) {
				return;
			}

			// once the binding is modified we always return the modified binding
			// and don't wanna modifiy the binding once again
			oBinding._modified = true;

			// set the table into grouping mode
			TableGrouping.setGroupMode(oTable);

			// we use sorting finally to sort the values and afterwards group them
			var sPropertyName = oGroupBy.getSortProperty();
			oBinding.sort(new Sorter(sPropertyName));

			// fetch the contexts from the original binding
			var iLength = oTable._getTotalRowCount(),
				aContexts = oBinding.getContexts(0, iLength);

			// add the context information for the group headers which are later on
			// used for displaying the grouping information of each group
			var sKey;
			var iCounter = 0;
			for (var i = iLength - 1; i >= 0; i--) {
				var sNewKey = aContexts[i].getProperty(sPropertyName);
				if (!sKey) {
					sKey = sNewKey;
				}
				if (sKey !== sNewKey) {
					var oGroupContext = aContexts[i + 1].getModel().getContext("/sap.ui.table.GroupInfo" + i);
					oGroupContext.__groupInfo = {
						oContext: aContexts[i + 1],
						name: sKey,
						count: iCounter,
						groupHeader: true,
						expanded: true
					};
					aContexts.splice(i + 1, 0,
						oGroupContext
					);
					sKey = sNewKey;
					iCounter = 0;
				}
				iCounter++;
			}
			var oGroupContext = aContexts[0].getModel().getContext("/sap.ui.table.GroupInfo");
			oGroupContext.__groupInfo = {
				oContext: aContexts[0],
				name: sKey,
				count: iCounter,
				groupHeader: true,
				expanded: true
			};
			aContexts.splice(0, 0, oGroupContext);

			// extend the binding and hook into the relevant functions to provide access to the grouping information
			// TODO: Unify this with the "look&feel" of the binding in the TreeTable --> _updateTableContent must only be implemented once
			jQuery.extend(oBinding, {
				getLength: function() {
					return aContexts.length;
				},
				getContexts: function(iStartIndex, iLength) {
					return aContexts.slice(iStartIndex, iStartIndex + iLength);
				},
				isGroupHeader: function(iIndex) {
					var oContext = aContexts[iIndex];
					return (oContext && oContext.__groupInfo && oContext.__groupInfo.groupHeader) === true;
				},
				getTitle: function(iIndex) {
					var oContext = aContexts[iIndex];
					return oContext && oContext.__groupInfo && oContext.__groupInfo.name + " - " + oContext.__groupInfo.count;
				},
				isExpanded: function(iIndex) {
					var oContext = aContexts[iIndex];
					return this.isGroupHeader(iIndex) && oContext.__groupInfo && oContext.__groupInfo.expanded;
				},
				expand: function(iIndex) {
					if (this.isGroupHeader(iIndex) && !aContexts[iIndex].__groupInfo.expanded) {
						for (var i = 0; i < aContexts[iIndex].__childs.length; i++) {
							aContexts.splice(iIndex + 1 + i, 0, aContexts[iIndex].__childs[i]);
						}
						delete aContexts[iIndex].__childs;
						aContexts[iIndex].__groupInfo.expanded = true;
						this._fireChange();
					}
				},
				collapse: function(iIndex) {
					if (this.isGroupHeader(iIndex) && aContexts[iIndex].__groupInfo.expanded) {
						aContexts[iIndex].__childs = aContexts.splice(iIndex + 1, aContexts[iIndex].__groupInfo.count);
						aContexts[iIndex].__groupInfo.expanded = false;
						this._fireChange();
					}
				},
				toggleIndex: function(iIndex) {
					if (this.isExpanded(iIndex)) {
						this.collapse(iIndex);
					} else {
						this.expand(iIndex);
					}
				},

				// For compatibility with TreeBinding adapters.
				nodeHasChildren: function(oContext) {
					if (!oContext || !oContext.__groupInfo) {
						return false;
					} else {
						return oContext.__groupInfo.groupHeader === true;
					}
				},
				getNodeByIndex: function(iIndex) {
					return aContexts[iIndex];
				}
			});

			// the table need to fetch the updated/changed contexts again, therefore requires the binding to fire a change event
			oTable._mTimeouts.groupingFireBindingChange = oTable._mTimeouts.groupingFireBindingChange || window.setTimeout(
				function() {oBinding._fireChange();}, 0);
		}
function ( oTable ) { if ( ! oTable . getEnableGrouping ( ) ) { return ; } var oBinding = Element . prototype . getBinding . call ( oTable , "rows" ) ; // check for grouping being supported or not (only for client ListBindings!!) var oGroupBy = sap . ui . getCore ( ) . byId ( oTable . getGroupBy ( ) ) ; var bIsSupported = oGroupBy && oGroupBy . getGrouped ( ) && TableGrouping . TableUtils . isA ( oBinding , "sap.ui.model.ClientListBinding" ) ; // only enhance the binding if it has not been done yet and supported! if ( ! bIsSupported || oBinding . _modified ) { return ; } // once the binding is modified we always return the modified binding // and don't wanna modifiy the binding once again oBinding . _modified = true ; // set the table into grouping mode TableGrouping . setGroupMode ( oTable ) ; // we use sorting finally to sort the values and afterwards group them var sPropertyName = oGroupBy . getSortProperty ( ) ; oBinding . sort ( new Sorter ( sPropertyName ) ) ; // fetch the contexts from the original binding var iLength = oTable . _getTotalRowCount ( ) , aContexts = oBinding . getContexts ( 0 , iLength ) ; // add the context information for the group headers which are later on // used for displaying the grouping information of each group var sKey ; var iCounter = 0 ; for ( var i = iLength - 1 ; i >= 0 ; i -- ) { var sNewKey = aContexts [ i ] . getProperty ( sPropertyName ) ; if ( ! sKey ) { sKey = sNewKey ; } if ( sKey !== sNewKey ) { var oGroupContext = aContexts [ i + 1 ] . getModel ( ) . getContext ( "/sap.ui.table.GroupInfo" + i ) ; oGroupContext . __groupInfo = { oContext : aContexts [ i + 1 ] , name : sKey , count : iCounter , groupHeader : true , expanded : true } ; aContexts . splice ( i + 1 , 0 , oGroupContext ) ; sKey = sNewKey ; iCounter = 0 ; } iCounter ++ ; } var oGroupContext = aContexts [ 0 ] . getModel ( ) . getContext ( "/sap.ui.table.GroupInfo" ) ; oGroupContext . __groupInfo = { oContext : aContexts [ 0 ] , name : sKey , count : iCounter , groupHeader : true , expanded : true } ; aContexts . splice ( 0 , 0 , oGroupContext ) ; // extend the binding and hook into the relevant functions to provide access to the grouping information // TODO: Unify this with the "look&feel" of the binding in the TreeTable --> _updateTableContent must only be implemented once jQuery . extend ( oBinding , { getLength : function ( ) { return aContexts . length ; } , getContexts : function ( iStartIndex , iLength ) { return aContexts . slice ( iStartIndex , iStartIndex + iLength ) ; } , isGroupHeader : function ( iIndex ) { var oContext = aContexts [ iIndex ] ; return ( oContext && oContext . __groupInfo && oContext . __groupInfo . groupHeader ) === true ; } , getTitle : function ( iIndex ) { var oContext = aContexts [ iIndex ] ; return oContext && oContext . __groupInfo && oContext . __groupInfo . name + " - " + oContext . __groupInfo . count ; } , isExpanded : function ( iIndex ) { var oContext = aContexts [ iIndex ] ; return this . isGroupHeader ( iIndex ) && oContext . __groupInfo && oContext . __groupInfo . expanded ; } , expand : function ( iIndex ) { if ( this . isGroupHeader ( iIndex ) && ! aContexts [ iIndex ] . __groupInfo . expanded ) { for ( var i = 0 ; i < aContexts [ iIndex ] . __childs . length ; i ++ ) { aContexts . splice ( iIndex + 1 + i , 0 , aContexts [ iIndex ] . __childs [ i ] ) ; } delete aContexts [ iIndex ] . __childs ; aContexts [ iIndex ] . __groupInfo . expanded = true ; this . _fireChange ( ) ; } } , collapse : function ( iIndex ) { if ( this . isGroupHeader ( iIndex ) && aContexts [ iIndex ] . __groupInfo . expanded ) { aContexts [ iIndex ] . __childs = aContexts . splice ( iIndex + 1 , aContexts [ iIndex ] . __groupInfo . count ) ; aContexts [ iIndex ] . __groupInfo . expanded = false ; this . _fireChange ( ) ; } } , toggleIndex : function ( iIndex ) { if ( this . isExpanded ( iIndex ) ) { this . collapse ( iIndex ) ; } else { this . expand ( iIndex ) ; } } , // For compatibility with TreeBinding adapters. nodeHasChildren : function ( oContext ) { if ( ! oContext || ! oContext . __groupInfo ) { return false ; } else { return oContext . __groupInfo . groupHeader === true ; } } , getNodeByIndex : function ( iIndex ) { return aContexts [ iIndex ] ; } } ) ; // the table need to fetch the updated/changed contexts again, therefore requires the binding to fire a change event oTable . _mTimeouts . groupingFireBindingChange = oTable . _mTimeouts . groupingFireBindingChange || window . setTimeout ( function ( ) { oBinding . _fireChange ( ) ; } , 0 ) ; }
/*
EXPERIMENTAL Grouping Feature of sap.ui.table.Table:

Overrides the getBinding to inject the grouping information into the JSON model.

TODO:
- Grouping is not really possible for models based on OData:
- it works when loading data from the beginning because in this case the
model has the relevant information (distinct values) to determine the
count of rows and add them properly in the scrollbar as well as adding
the group information to the contexts array which is used by the
_modifyRow to display the group headers
- it doesn't work when not knowing how many groups are available before
and on which position the group header has to be added - e.g. when
displaying a snapshot in the middle of the model.
- For OData it might be a server-side feature?
 
Initializes the experimental grouping for sap.ui.table.Table.

@param {sap.ui.table.Table} oTable Instance of the table.
/ * EXPERIMENTAL Grouping Feature of sap . ui . table . Table :
Returns the binding for the table rows