// polyfill lodash.keyBy, which was introduced in lodash 4, since sails only exposes lodash 3.
const keyBy = (collection, iteratee) => _.mapValues(_.groupBy(collection, iteratee), 0);

function _getOrderedItemList (parent, contentsKey, orderedIdsKey) {
  const mapById = keyBy(parent[contentsKey], 'id');
  return parent[orderedIdsKey]
    .filter(id => _.has(mapById, id) && !mapById[id]._markedForDeletion)
    .map(id => mapById[id]);
}
module.exports = {
  getOrderedPokemonList: _.partial(_getOrderedItemList, _, 'contents', '_orderedIds'),
  getOrderedBoxList: _.partial(_getOrderedItemList, _, 'boxes', '_orderedBoxIds'),
  addPkmnIdsToBox (boxId, pkmnIds, position) {
    return Promise.fromCallback(Box.native.bind(Box)).then(collection => {
      const query = {$push: {_orderedIds: {$each: pkmnIds}}};
      if (_.isNumber(position)) {
        query.$push._orderedIds.$position = position;
      }
      return collection.update({_id: boxId}, query);
    });
  },

  removePkmnIdFromBox (boxId, pkmnId) {
    return Promise.fromCallback(Box.native.bind(Box)).then(collection => {
      return collection.update({_id: boxId}, {$pull: {_orderedIds: pkmnId}});
    });
  },

  addBoxIdsToUser (username, boxIds, position) {
    return Promise.fromCallback(User.native.bind(User)).then(collection => {
      const query = {$push: {_orderedBoxIds: {$each: boxIds}}};
      if (_.isNumber(position)) {
        query.$push._orderedBoxIds.$position = position;
      }
      return collection.update({_id: username}, query);
    });
  },

  removeBoxIdFromUser (username, boxId) {
    return Promise.fromCallback(User.native.bind(User)).then(collection => {
      return collection.update({_id: username}, {$pull: {_orderedBoxIds: boxId}});
    });
  }
};

@@ -304,36 +304,606 @@
 ;%0A  
-return parent%5BorderedIdsKey%5D
+const uniqList = _.uniq(parent%5BorderedIdsKey%5D);%0A  const id = contentsKey === 'contents' ? parent.id : parent.name;%0A  const missingIds = _.difference(Object.keys(mapById), uniqList);%0A  if (missingIds.length) %7B%0A    // should not happen, but might due to database issues%0A    sails.log.warn(%60The following $%7BorderedIdsKey%7D are missing from the item with id $%7Bid%0A    %7D: $%7BmissingIds%7D. They will be added to the end of the list.%60);%0A    if (contentsKey === 'contents') BoxOrdering.addPkmnIdsToBox(parent.id, missingIds);%0A    else BoxOrdering.addBoxIdsToUser(parent.name, missingIds);%0A  %7D%0A  return uniqList
 %0A   

Add sanity checks for database inconsistencies