code: function(num) {
      // FIXME: keep the "free" list sorted, so we can binary search it
      // for a good match
      var bestIndex = -1;
      var bestLength = null;
      for (var i = 0; i < this._free.length; ++i) {
        var free = this._free[i];
        var length = free.length();
        if (length >= num && (bestLength === null || length < bestLength)) {
          bestLength = length;
          bestIndex = i;
        }
      }
      if (bestIndex !== -1) {
        var result = this._free[bestIndex];
        this._free.splice(bestIndex, 1);
        this._usedCount ++;
        return result;
      }
      var start = this._unusedRangeStart;
      var end = start + num;
      if (end > this.MAX_ID) {
        console.error('not enough free object ids.');
        return null;
      }
      this._unusedRangeStart = end;
      var newRange = new ContinuousIdRange(this, start, end);
      this._usedCount ++;
      return newRange;
    }
docs: 2^24