function findMatchingController (controllers, filterIdExact, filterIdPrefix, filterHand,
                                 filterControllerIndex) {
  var controller;
  var filterIdPrefixes;
  var i;
  var j;
  var matches;
  var matchingControllerOccurence = 0;
  var prefix;
  var targetControllerMatch = filterControllerIndex || 0;

  // Check whether multiple prefixes.
  if (filterIdPrefix && filterIdPrefix.indexOf('|') >= 0) {
    filterIdPrefixes = split(filterIdPrefix, '|');
  }

  for (i = 0; i < controllers.length; i++) {
    controller = controllers[i];

    // Determine if the controller ID matches our criteria.
    if (filterIdPrefixes) {
      matches = false;
      for (j = 0; j < filterIdPrefixes.length; j++) {
        prefix = filterIdPrefixes[j];
        if (prefix && controller.id.startsWith(prefix)) {
          matches = true;
          break;
        }
      }
      if (!matches) { continue; }
    } else if (filterIdPrefix && controller.id.indexOf(filterIdPrefix)) {
      continue;
    }

    if (!filterIdPrefix && controller.id !== filterIdExact) { continue; }

    // If the hand filter and controller handedness are defined we compare them.
    if (filterHand && controller.hand && filterHand !== controller.hand) { continue; }

    // If we have detected an unhanded controller and the component was asking
    // for a particular hand, we need to treat the controllers in the array as
    // pairs of controllers. This effectively means that we need to skip
    // NUM_HANDS matches for each controller number, instead of 1.
    if (filterHand && !controller.hand) {
      targetControllerMatch = NUM_HANDS * filterControllerIndex + ((filterHand === DEFAULT_HANDEDNESS) ? 0 : 1);
    }

    // We are looking for the nth occurence of a matching controller
    // (n equals targetControllerMatch).
    if (matchingControllerOccurence === targetControllerMatch) { return controller; }
    ++matchingControllerOccurence;
  }
  return undefined;
}
Walk through the given controllers to find any where the device ID equals
filterIdExact, or startWith filterIdPrefix.
A controller where this considered true is considered a 'match'.

For each matching controller:
  If filterHand is set, and the controller:
    is handed, we further verify that controller.hand equals filterHand.
    is unhanded (controller.hand is ''), we skip until we have found a
    number of matching controllers that equals filterControllerIndex
  If filterHand is not set, we skip until we have found the nth matching
  controller, where n equals filterControllerIndex

The method should be called with one of: [filterIdExact, filterIdPrefix] AND
one or both of: [filterHand, filterControllerIndex]

@param {object} controllers - Array of gamepads to search
@param {string} filterIdExact - If set, used to find controllers with id === this value
@param {string} filterIdPrefix - If set, used to find controllers with id startsWith this value
@param {object} filterHand - If set, further filters controllers with matching 'hand' property
@param {object} filterControllerIndex - Find the nth matching controller,
where n equals filterControllerIndex. defaults to 0.