/**
   * convert a GTSWrapper into GeoTimeSerie
   *
   * @param wrapper
   * @return GeoTimeSerie
   */
  public static GeoTimeSerie fromGTSWrapperToGTS(GTSWrapper wrapper) {

    Metadata metadata = wrapper.getMetadata();
    GeoTimeSerie gts = null;

    if (null != wrapper.getEncoded()) {

      byte[] bytes = null;

      if (wrapper.isCompressed()) {
        bytes = unwrapEncoded(wrapper);
      } else {
        bytes = wrapper.getEncoded();
      }

      ByteBuffer bb = ByteBuffer.wrap(bytes);

      GTSDecoder decoder = new GTSDecoder(wrapper.getBase(), bb);

      decoder.setCount(0 != wrapper.getCount() ? wrapper.getCount() : bytes.length / 10);

      gts = decoder.decode();

    } else {
      gts = new GeoTimeSerie();
    }

    if (null == metadata) {
      metadata = new Metadata();
    }

    gts.setMetadata(metadata);

    return gts;
  }
  /**
   * Method used to rewrap a GTSWrapper, typically to change the compression settings.
   *
   * @param wrapper
   * @param compress
   * @param compratio
   * @return
   */
  public static GTSWrapper rewrap(GTSWrapper wrapper, boolean compress, double compratio) {
    byte[] unwrapped = unwrapEncoded(wrapper);

    GTSEncoder encoder = new GTSEncoder(wrapper.getBase(), null, unwrapped);

    GTSWrapper tmp = fromGTSEncoderToGTSWrapper(encoder, compress, compratio);

    GTSWrapper rewrapped = new GTSWrapper(wrapper);
    rewrapped.setCompressed(tmp.isCompressed());
    rewrapped.setCompressionPasses(tmp.getCompressionPasses());
    rewrapped.setEncoded(tmp.getEncoded());

    return rewrapped;
  }
  /**
   * Extract the encoded data, removing compression if needed
   *
   * @param wrapper from which to extract the encoded data
   * @return the raw encoded data
   */
  private static byte[] unwrapEncoded(GTSWrapper wrapper) {

    if (!wrapper.isCompressed()) {
      return wrapper.getEncoded();
    }

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    byte[] bytes = wrapper.getEncoded();

    int pass = wrapper.getCompressionPasses();

    while (pass > 0) {
      ByteArrayInputStream in = new ByteArrayInputStream(bytes);
      baos.reset();

      try {
        GZIPInputStream gzis = new GZIPInputStream(in);
        byte[] buf = new byte[1024];

        while (true) {
          int len = gzis.read(buf);

          if (len < 0) {
            break;
          }

          baos.write(buf, 0, len);
        }

        gzis.close();
      } catch (IOException ioe) {
        throw new RuntimeException("Invalid compressed content.");
      }
      bytes = baos.toByteArray();
      pass--;
    }

    return bytes;
  }