function _serializeBatchRequest(aRequests, iChangeSetIndex, sEpilogue, bIgnoreETag) {
		var sBatchBoundary = (iChangeSetIndex !== undefined ? "changeset_" : "batch_")
				+ _Helper.uid(),
			bIsChangeSet = iChangeSetIndex !== undefined,
			aRequestBody = [];

		if (bIsChangeSet) {
			aRequestBody.push("Content-Type: multipart/mixed;boundary=",
				sBatchBoundary, "\r\n\r\n");
		}
		aRequests.forEach(function (oRequest, iRequestIndex) {
			var sContentIdHeader = "",
				sUrl = oRequest.url;

			if (bIsChangeSet) {
				oRequest.$ContentID = iRequestIndex + "." + iChangeSetIndex;
				sContentIdHeader = "Content-ID:" + oRequest.$ContentID + "\r\n";
			}

			aRequestBody.push("--", sBatchBoundary, "\r\n");
			if (Array.isArray(oRequest)) {
				if (bIsChangeSet) {
					throw new Error("Change set must not contain a nested change set.");
				}
				aRequestBody = aRequestBody.concat(
					_serializeBatchRequest(oRequest, iRequestIndex, "", bIgnoreETag).body);
			} else {
				if (bIsChangeSet && !mAllowedChangeSetMethods[oRequest.method]) {
					throw new Error("Invalid HTTP request method: " + oRequest.method
						+ ". Change set must contain only POST, PUT, PATCH, or DELETE requests.");
				}

				if (iChangeSetIndex !== undefined && sUrl[0] === "$") {
					// adjust URL if it starts with a Content-ID reference by adding the change set
					// index
					if (sUrl === "$-1") { // reference the previous request
						sUrl = "$" + (iRequestIndex - 1) + "." + iChangeSetIndex;
					} else {
						sUrl = sUrl.replace(rContentIdReference, "$&." + iChangeSetIndex);
					}
				}

				aRequestBody = aRequestBody.concat(
					"Content-Type:application/http\r\n",
					"Content-Transfer-Encoding:binary\r\n",
					sContentIdHeader,
					"\r\n",
					oRequest.method, " ", sUrl, " HTTP/1.1\r\n",
					serializeHeaders(_Helper.resolveIfMatchHeader(oRequest.headers, bIgnoreETag)),
					"\r\n",
					JSON.stringify(oRequest.body) || "", "\r\n");
			}
		});
		aRequestBody.push("--", sBatchBoundary, "--\r\n", sEpilogue);

		return {body : aRequestBody, batchBoundary : sBatchBoundary};
	}
Serializes the given array of request objects into a $batch request body.

@param {object[]} aRequests
  An array consisting of request objects or arrays of request objects, in case requests need
  to be sent in scope of a change set. Change set requests are annotated with a property
  <code>$ContentID</code> containing the corresponding Content-ID from the serialized batch
  request body.
@param {number} [iChangeSetIndex]
  Is only specified if the function is called to serialize change sets and
  contains zero-based index of the change set within <code>aRequests</code> array.
@param {string} [sEpilogue]
  String that will be included in the epilogue
@param {boolean} [bIgnoreETag]
  Whether an entity's ETag should be actively ignored (If-Match:*) for PATCH requests;
  ignored if there is no ETag
@returns {object}
  The $batch request object with the following structure
  <ul>
    <li> <code>body</code>: {string[]} Array of strings representing batch request body
    <li> <code>batchBoundary</code>: {string} Batch boundary value
  </ul>
@throws {Error}
  If change sets are nested or an HTTP method other than GET, POST, PUT, PATCH, or DELETE is
  used