text: O.esri.Tiles.TilingScheme = function (layer) {
      this.tileInfo = layer.tileInfo;
  };
  
  O.esri.Tiles.TilingScheme.prototype = {
      getCellIdFromXy: function (x, y, level) {
          var col = Math.floor((x - this.tileInfo.origin.x) / (this.tileInfo.cols * this.tileInfo.lods[level].resolution));
          var row = Math.floor((this.tileInfo.origin.y - y) / (this.tileInfo.rows * this.tileInfo.lods[level].resolution));
          return [col, row];
      },
  
      getCellPolygonFromCellId: function (cellId, level) {
          var col1 = cellId[0];
          var row1 = cellId[1];
          var col2 = col1 + 1;
          var row2 = row1 + 1;
  
          var x1 = this.tileInfo.origin.x + (col1 * this.tileInfo.cols * this.tileInfo.lods[level].resolution);
          var y1 = this.tileInfo.origin.y - (row1 * this.tileInfo.rows * this.tileInfo.lods[level].resolution);
          var x2 = this.tileInfo.origin.x + (col2 * this.tileInfo.cols * this.tileInfo.lods[level].resolution);
          var y2 = this.tileInfo.origin.y - (row2 * this.tileInfo.rows * this.tileInfo.lods[level].resolution);
  
          var polygon;
          var spatialReference = this.tileInfo.spatialReference;
  
          require(["esri/geometry/Polygon"],function(Polygon){
              polygon = new Polygon(spatialReference);
          });
  
          polygon.addRing([
              [x1, y1], // clockwise
              [x2, y1],
              [x2, y2],
              [x1, y2],
              [x1, y1]
          ]);
          return polygon;
      },
  
      getAllCellIdsInExtent: function (extent, gridLevel) {
          var cellId0 = this.getCellIdFromXy(extent.xmin, extent.ymin, gridLevel);
          var cellId1 = this.getCellIdFromXy(extent.xmax, extent.ymax, gridLevel);
  
          var i, j;
          var i0 = Math.max(Math.min(cellId0[0], cellId1[0]), this.tileInfo.lods[gridLevel].startTileCol);
          var i1 = Math.min(Math.max(cellId0[0], cellId1[0]), this.tileInfo.lods[gridLevel].endTileCol);
          var j0 = Math.max(Math.min(cellId0[1], cellId1[1]), this.tileInfo.lods[gridLevel].startTileRow);
          var j1 = Math.min(Math.max(cellId0[1], cellId1[1]), this.tileInfo.lods[gridLevel].endTileRow);
  
          var cellIds = [];
  
          for (i = i0; i <= i1; i++) {
              for (j = j0; j <= j1; j++) {
                  cellIds.push([i, j]);
              }
          }
          return cellIds;
      }
  };
  
  