function (expected, args, minimum) {
   var shiftedArgs = [];
   var curArg = args.length - 1;
   var remainingOptionalArgs = expected.length - minimum;
   var optionalIndiceSegments = [];
   var optionalIndiceSegment = [];
   var availableArgsSegments = [];
   var availableArgsSegment = [];

   // Fill the return array with nulls first.
   for (var i = 0; i < expected.length; i++) shiftedArgs[i] = null;

   // Capture groups of available arguments separated by ones that have been used.
   var advanceArg = function () {
      availableArgsSegment.unshift(curArg);
      curArg--;
      remainingOptionalArgs--;
      if (curArg < 0 || remainingOptionalArgs < 0) {
         throw Error(getExpectedVsRecieved_(expected, args));
      }
   };

   // Fill in all of the required types, starting from the last expected argument and working
   // towards the first.
   for (i = expected.length - 1; i >= 0; i--) {
      var type = expected[i];
      if (isOptionalType(type)) {
         optionalIndiceSegment.unshift(i);
         continue;
      }
      // Keep moving down the line of arguments until one matches.
      while (!isOfType(args[curArg], type)) {
         advanceArg();
      }

      // Check if this argument should be left for a trailing optional argument.
      if (checkIfShouldLeaveArgument_(expected, i, args, curArg)) {
         // Found enough matches to let this be an optional argument. Advance the argument and
         // then restart on this same function.
         advanceArg();
         i++;
         continue;
      }

      // Capture groups of optional arguments separated by required arguments.
      optionalIndiceSegments.unshift(optionalIndiceSegment);
      optionalIndiceSegment = [];
      availableArgsSegments.unshift(availableArgsSegment);
      availableArgsSegment = []
      shiftedArgs[i] = args[curArg--];
   }
   // Now that we have found all the required arguments, group the rest for processing with optional
   // arguments.
   while (curArg >= 0) availableArgsSegment.unshift(curArg--);
   availableArgsSegments.unshift(availableArgsSegment);
   optionalIndiceSegments.unshift(optionalIndiceSegment);

   // Make sure that the optional argument count matches up correctly.
   if (availableArgsSegments.length != optionalIndiceSegments.length) {
      throw Error(getExpectedVsRecieved_(expected, args));
   }

   // Go through all the optional segments and argument segments to match up the optional arguments.
   optionalIndiceSegments.forEach(function (optionalIndices, index) {
      availableArgsSegment = availableArgsSegments[index];
      i = 0;
      availableArgsSegment.forEach(function (argIndex) {
         arg = args[argIndex]
         // Skip forward until we find an optional expected argument that matches.
         while (!isOfType(arg, expected[optionalIndices[i]]) && i < optionalIndices.length) {
            i++;
         }
         // If none match then the arguments are invalid.
         if (i >= optionalIndices.length) {
            throw Error(getExpectedVsRecieved_(expected, args));
         }
         // Success! This is an optional expected argument.
         shiftedArgs[optionalIndices[i++]] = arg;
      });
   });

   return shiftedArgs;
}
function (expected, args, minimum) {
   var shiftedArgs = [];
   var curArg = args.length - 1;
   var remainingOptionalArgs = expected.length - minimum;
   var optionalIndiceSegments = [];
   var optionalIndiceSegment = [];
   var availableArgsSegments = [];
   var availableArgsSegment = [];

   // Fill the return array with nulls first.
   for (var i = 0; i < expected.length; i++) shiftedArgs[i] = null;

   // Capture groups of available arguments separated by ones that have been used.
   var advanceArg = function () {
      availableArgsSegment.unshift(curArg);
      curArg--;
      remainingOptionalArgs--;
      if (curArg < 0 || remainingOptionalArgs < 0) {
         throw Error(getExpectedVsRecieved_(expected, args));
      }
   };

   // Fill in all of the required types, starting from the last expected argument and working
   // towards the first.
   for (i = expected.length - 1; i >= 0; i--) {
      var type = expected[i];
      if (isOptionalType(type)) {
         optionalIndiceSegment.unshift(i);
         continue;
      }
      // Keep moving down the line of arguments until one matches.
      while (!isOfType(args[curArg], type)) {
         advanceArg();
      }

      // Check if this argument should be left for a trailing optional argument.
      if (checkIfShouldLeaveArgument_(expected, i, args, curArg)) {
         // Found enough matches to let this be an optional argument. Advance the argument and
         // then restart on this same function.
         advanceArg();
         i++;
         continue;
      }

      // Capture groups of optional arguments separated by required arguments.
      optionalIndiceSegments.unshift(optionalIndiceSegment);
      optionalIndiceSegment = [];
      availableArgsSegments.unshift(availableArgsSegment);
      availableArgsSegment = []
      shiftedArgs[i] = args[curArg--];
   }
   // Now that we have found all the required arguments, group the rest for processing with optional
   // arguments.
   while (curArg >= 0) availableArgsSegment.unshift(curArg--);
   availableArgsSegments.unshift(availableArgsSegment);
   optionalIndiceSegments.unshift(optionalIndiceSegment);

   // Make sure that the optional argument count matches up correctly.
   if (availableArgsSegments.length != optionalIndiceSegments.length) {
      throw Error(getExpectedVsRecieved_(expected, args));
   }

   // Go through all the optional segments and argument segments to match up the optional arguments.
   optionalIndiceSegments.forEach(function (optionalIndices, index) {
      availableArgsSegment = availableArgsSegments[index];
      i = 0;
      availableArgsSegment.forEach(function (argIndex) {
         arg = args[argIndex]
         // Skip forward until we find an optional expected argument that matches.
         while (!isOfType(arg, expected[optionalIndices[i]]) && i < optionalIndices.length) {
            i++;
         }
         // If none match then the arguments are invalid.
         if (i >= optionalIndices.length) {
            throw Error(getExpectedVsRecieved_(expected, args));
         }
         // Success! This is an optional expected argument.
         shiftedArgs[optionalIndices[i++]] = arg;
      });
   });

   return shiftedArgs;
}
function ( expected , args , minimum ) { var shiftedArgs = [ ] ; var curArg = args . length - 1 ; var remainingOptionalArgs = expected . length - minimum ; var optionalIndiceSegments = [ ] ; var optionalIndiceSegment = [ ] ; var availableArgsSegments = [ ] ; var availableArgsSegment = [ ] ; // Fill the return array with nulls first. for ( var i = 0 ; i < expected . length ; i ++ ) shiftedArgs [ i ] = null ; // Capture groups of available arguments separated by ones that have been used. var advanceArg = function ( ) { availableArgsSegment . unshift ( curArg ) ; curArg -- ; remainingOptionalArgs -- ; if ( curArg < 0 || remainingOptionalArgs < 0 ) { throw Error ( getExpectedVsRecieved_ ( expected , args ) ) ; } } ; // Fill in all of the required types, starting from the last expected argument and working // towards the first. for ( i = expected . length - 1 ; i >= 0 ; i -- ) { var type = expected [ i ] ; if ( isOptionalType ( type ) ) { optionalIndiceSegment . unshift ( i ) ; continue ; } // Keep moving down the line of arguments until one matches. while ( ! isOfType ( args [ curArg ] , type ) ) { advanceArg ( ) ; } // Check if this argument should be left for a trailing optional argument. if ( checkIfShouldLeaveArgument_ ( expected , i , args , curArg ) ) { // Found enough matches to let this be an optional argument. Advance the argument and // then restart on this same function. advanceArg ( ) ; i ++ ; continue ; } // Capture groups of optional arguments separated by required arguments. optionalIndiceSegments . unshift ( optionalIndiceSegment ) ; optionalIndiceSegment = [ ] ; availableArgsSegments . unshift ( availableArgsSegment ) ; availableArgsSegment = [ ] shiftedArgs [ i ] = args [ curArg -- ] ; } // Now that we have found all the required arguments, group the rest for processing with optional // arguments. while ( curArg >= 0 ) availableArgsSegment . unshift ( curArg -- ) ; availableArgsSegments . unshift ( availableArgsSegment ) ; optionalIndiceSegments . unshift ( optionalIndiceSegment ) ; // Make sure that the optional argument count matches up correctly. if ( availableArgsSegments . length != optionalIndiceSegments . length ) { throw Error ( getExpectedVsRecieved_ ( expected , args ) ) ; } // Go through all the optional segments and argument segments to match up the optional arguments. optionalIndiceSegments . forEach ( function ( optionalIndices , index ) { availableArgsSegment = availableArgsSegments [ index ] ; i = 0 ; availableArgsSegment . forEach ( function ( argIndex ) { arg = args [ argIndex ] // Skip forward until we find an optional expected argument that matches. while ( ! isOfType ( arg , expected [ optionalIndices [ i ] ] ) && i < optionalIndices . length ) { i ++ ; } // If none match then the arguments are invalid. if ( i >= optionalIndices . length ) { throw Error ( getExpectedVsRecieved_ ( expected , args ) ) ; } // Success! This is an optional expected argument. shiftedArgs [ optionalIndices [ i ++ ] ] = arg ; } ) ; } ) ; return shiftedArgs ; }
Returns an array of all of the arguments shifted into the correct place.
@param {Array} expected
@param {Array} actual
@returns {Array}
@private
Returns an array of all of the arguments shifted into the correct place .