docs: private DataPoints scale(final DataPoints points, final double scale_factor) {
      // TODO(cl) - Using an array as the size function may not return the exact
      // results and we should figure a way to avoid copying data anyway.
      final List<DataPoint> dps = new ArrayList<DataPoint>();
      final boolean scale_is_int = (scale_factor == Math.floor(scale_factor)) && 
          !Double.isInfinite(scale_factor);
      final SeekableView view = points.iterator();
      while (view.hasNext()) {
        DataPoint pt = view.next();
        if (pt.isInteger() && scale_is_int) {
          dps.add(MutableDataPoint.ofLongValue(pt.timestamp(), 
              (long)scale_factor * pt.longValue()));
        } else {
          // NaNs are fine here, they'll just be re-computed as NaN
          dps.add(MutableDataPoint.ofDoubleValue(pt.timestamp(), 
              scale_factor * pt.toDouble()));
        }
      }
      final DataPoint[] results = new DataPoint[dps.size()];
      dps.toArray(results);
      return new PostAggregatedDataPoints(points, results);
    }