code: function sortPaths(items/* , [iteratee, ] dirSeparator */) {
      assert(arguments.length >= 2, 'too few arguments');
      assert(arguments.length <= 3, 'too many arguments');
  
      var iteratee, dirSeparator;
  
      if (arguments.length === 2) {
          iteratee = identity;
          dirSeparator = arguments[1];
      }
      else {
          iteratee = arguments[1];
          dirSeparator = arguments[2];
      }
  
      assert(isArray(items), 'items is not an array');
      assert(isFunction(iteratee), 'iteratee is not a function');
      assert(typeof dirSeparator === 'string', 'dirSeparator is not a String');
      assert(dirSeparator.length === 1, 'dirSeparator must be a single character');
  
      //encapsulate into DTOs
      var itemDTOs = items.map(function (item) {
          var path = iteratee(item);
  
          assert(typeof path === 'string', 'item or iteratee(item) must be a String');
  
          return {
              item: item,
              pathTokens: splitRetain(path, dirSeparator)
          };
      });
  
      //sort DTOs
      itemDTOs.sort(createItemDTOComparator(dirSeparator));
  
      //decapsulate sorted DTOs and return
      return itemDTOs.map(function (itemDTO) {
          return itemDTO.item;
      });
  }
docs: Allows sorting arbitrary items without modifying or copying them
  
  @typedef {Object} itemDTO
  
  @param {String|Object} item - original item
  @param {Array} pathTokens - split path tokens. Extracted from `item` using `iteratee` and split using `splitRetain`