static void dump(grib_accessor* a,grib_dumper* dumper)
{
  grib_accessor_lookup* self = (grib_accessor_lookup*)a;
  unsigned char bytes[1024] = {0,};
  char msg[1024]= {0,};
  char buf[1024];
  int i;
  unsigned long v = 0;

  size_t llen = self->llength;
  grib_unpack_bytes(a, bytes, &llen); /* TODO: Unpack byte unpack the wrong offset */

  bytes[llen] = 0;
  for(i = 0; i < llen; i++)
  {
    msg[i] = isprint(bytes[i]) ? bytes[i] : '?';
    v <<= 8;
    v |= bytes[i];
  }

  msg[llen] = 0;

  sprintf(buf,"%s %ld %ld-%ld",msg,v,(long)a->offset+self->loffset,(long)self->llength);

  grib_dump_long(dumper,a,buf);

}
static int unpack_string(grib_accessor*a , char*  v, size_t *len)
{
    grib_accessor_lookup* self = (grib_accessor_lookup*)a;
    unsigned char bytes[1024] = {0,};
    int i;

    size_t llen = self->llength;
    grib_unpack_bytes(a, bytes, &llen); /* TODO: Unpack byte unpack the wrong offset */

    bytes[llen] = 0;

    for(i = 0; i < llen; i++)
    {
        v[i] = isprint(bytes[i]) ? bytes[i] : '?';
    }

    v[llen] = 0;
    if (llen==1 && v[0] == '?') {
        /* Try unpack as long */
        size_t length = 10;
        long lval = 0;
        int err = unpack_long(a, &lval, &length);
        if (!err) {
            char str[5];
            int conv = sprintf(str, "%ld", lval);
            if (conv == 1) {
                v[0] = str[0];
            }
        }
    }

    return GRIB_SUCCESS;
}
static void dump_bytes(grib_dumper* d,grib_accessor* a,const char* comment)
{
  grib_dumper_c_code *self = (grib_dumper_c_code*)d;
  int err =0;
  size_t size = a->length;
  unsigned char* buf;


  if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY)
    return;

  if(size == 0)
    return;

  buf = grib_context_malloc(d->handle->context,size);

  if(!buf)
  {
    fprintf(self->dumper.out,"/* %s: cannot malloc(%ld) */\n",a->name,(long)size);
    return;
  }


  err = grib_unpack_bytes(a,buf,&size);
  if(err){
    grib_context_free(d->handle->context,buf);
    fprintf(self->dumper.out," *** ERR=%d (%s) \n}",err,grib_get_error_message(err));
    return ;
  }

#if 0
  if(size > 100) {
    more = size - 100;
    size = 100;
  }

  k = 0;
  /* if(size > 100) size = 100;  */
  while(k < size)
  {
    int j;
    for(i = 0; i < d->depth + 3 ; i++) fprintf(self->dumper.out," ");
    for(j = 0; j < 16 && k < size; j++, k++)
    {
      fprintf(self->dumper.out,"%02x",buf[k]);
      if(k != size-1)
        fprintf(self->dumper.out,", ");
    }
    fprintf(self->dumper.out,"\n");
  }
#endif
  grib_context_free(d->handle->context,buf);
}
static int unpack_string(grib_accessor*a , char*  v, size_t *len){

  grib_accessor_lookup* self = (grib_accessor_lookup*)a;
  unsigned char bytes[1024] = {0,};
  int i;

  size_t llen = self->llength;
  grib_unpack_bytes(a, bytes, &llen); /* TODO: Unpack byte unpack the wrong offset */

  bytes[llen] = 0;
  for(i = 0; i < llen; i++)
  {
    v[i] = isprint(bytes[i]) ? bytes[i] : '?';
  }

  v[llen] = 0;


  return GRIB_SUCCESS;

}
static void dump_bytes(grib_dumper* d,grib_accessor* a,const char* comment)
{
    grib_dumper_debug *self = (grib_dumper_debug*)d;
    int i,k,err =0;
    int more = 0;
    size_t size = a->length;
    unsigned char* buf = (unsigned char*)grib_context_malloc(d->handle->context,size);

    if( a->length == 0  &&
            (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0)
        return;

    set_begin_end(d,a);

    for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," ");
    fprintf(self->dumper.out,"%ld-%ld %s %s = %ld",self->begin,self->theEnd,a->creator->op, a->name,a->length);
    aliases(d,a);
    fprintf(self->dumper.out," {");

    if(!buf)
    {
        if(size == 0)
            fprintf(self->dumper.out,"}\n");
        else
            fprintf(self->dumper.out," *** ERR cannot malloc(%ld) }\n",(long)size);
        return;
    }

    fprintf(self->dumper.out,"\n");

    err = grib_unpack_bytes(a,buf,&size);
    if(err){
        grib_context_free(d->handle->context,buf);
        fprintf(self->dumper.out," *** ERR=%d (%s) [grib_dumper_debug::dump_bytes]\n}",err,grib_get_error_message(err));
        return ;
    }

    if(size > 100) {
        more = size - 100;
        size = 100;
    }

    k = 0;
    /* if(size > 100) size = 100;  */
    while(k < size)
    {
        int j;
        for(i = 0; i < d->depth + 3 ; i++) fprintf(self->dumper.out," ");
        for(j = 0; j < 16 && k < size; j++, k++)
        {
            fprintf(self->dumper.out,"%02x",buf[k]);
            if(k != size-1)
                fprintf(self->dumper.out,", ");
        }
        fprintf(self->dumper.out,"\n");
    }

    if(more)
    {
        for(i = 0; i < d->depth + 3 ; i++) fprintf(self->dumper.out," ");
        fprintf(self->dumper.out,"... %d more values\n",more);
    }

    for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," ");
    fprintf(self->dumper.out,"} # %s %s \n",a->creator->op, a->name);
    grib_context_free(d->handle->context,buf);
}
static void dump_bytes(grib_dumper* d,grib_accessor* a,const char* comment)
{
  grib_dumper_default *self = (grib_dumper_default*)d;

  if ( (a->flags & GRIB_ACCESSOR_FLAG_DUMP) == 0)
    return;

  fprintf(self->dumper.out,"  %s = <%ld byte%s>;\n", a->name, a->length, a->length>1?"s":"");

#if 0
  grib_dumper_default *self = (grib_dumper_default*)d;
  int i,k,err =0;
  int more = 0;
  size_t size = a->length;
  unsigned char* buf = grib_context_malloc(d->handle->context,size);

  if ( (a->flags & GRIB_ACCESSOR_FLAG_DUMP) == 0)
    return;


  if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY)
    fprintf(self->dumper.out,"-READ ONLY- ");

  /*for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," ");*/
  /*print_offset(self->dumper.out,self->begin,self->theEnd);*/
  if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0)
        fprintf(self->dumper.out,"%s ",a->creator->op);

  fprintf(self->dumper.out,"%s = %ld",a->name,a->length);
  aliases(d,a);
  fprintf(self->dumper.out," {");

  if(!buf)
  {
    if(size == 0)
      fprintf(self->dumper.out,"}\n");
    else
      fprintf(self->dumper.out," *** ERR cannot malloc(%ld) }\n",(long)size);
    return;
  }

  fprintf(self->dumper.out,"\n");

  err = grib_unpack_bytes(a,buf,&size);
  if(err){
    grib_context_free(d->handle->context,buf);
    fprintf(self->dumper.out," *** ERR=%d (%s) [grib_dumper_default::dump_bytes]\n}",err,grib_get_error_message(err));
    return ;
  }

  if(size > 100) {
    more = size - 100;
    size = 100;
  }

  k = 0;
  /* if(size > 100) size = 100;  */
  while(k < size)
  {
    int j;
    for(i = 0; i < d->depth + 3 ; i++) fprintf(self->dumper.out," ");
    for(j = 0; j < 16 && k < size; j++, k++)
    {
      fprintf(self->dumper.out,"%02x",buf[k]);
      if(k != size-1)
        fprintf(self->dumper.out,", ");
    }
    fprintf(self->dumper.out,"\n");
  }

  if(more)
  {
    for(i = 0; i < d->depth + 3 ; i++) fprintf(self->dumper.out," ");
    fprintf(self->dumper.out,"... %d more values\n",more);
  }

  for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," ");
  fprintf(self->dumper.out,"} # %s %s \n",a->creator->op, a->name);
  grib_context_free(d->handle->context,buf);
#endif
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
    grib_accessor_data_2order_packing* self =  (grib_accessor_data_2order_packing*)a;
    grib_handle* gh = grib_handle_of_accessor(a);

    size_t i = 0;
    size_t j = 0;
    size_t n_vals = *len;
    size_t buff_len = 0;
    double divisor = 1;
    long     vcount = 0;
    int      err = 0;
    long     bias = 0;
    double   reference_value;
    long     binary_scale_factor;
    long     bits_per_value;
    /*long     bit_per_val_rectified_for_gribex;*/
    long     decimal_scale_factor;
    long     n1 = 0;
    long     n2 = 0;
    long     p1 = 0;
    long    n_unused_bits = 0;
    long   used_bits = 0;
    long   offsetsection  = 0;
    long   snd_bitmap     = 0;
    long   snd_ordr_wdiff = 0;

    long   matrix_values  = 0;

    long   general_ext       = 0;
    long   boustrophedonic   = 0;
    long   two_ordr_spd      = 0;
    long   plus1_spd         = 0;

    long   octet_start_group = 0;
    long   width_spd_sp_desc = 0;

    unsigned char* buf        = NULL;
    unsigned char* buf_size_of_groups   = NULL;
    unsigned char* buf_width_of_group = NULL;
    unsigned char* buf_refs   = NULL;
    unsigned char* buf_vals   = NULL;

    double d = 0;

    unsigned long*  sec_val    = NULL;
    unsigned long*  group_val  = NULL;

    short  n_sp_diff = 0;
    unsigned char* bitmap=NULL;
    grib_accessor* abitmap=NULL;
    size_t bitmap_len=0;

#if KEEP_OLD == 1

#else
    second_order_packed* sd = NULL;
#endif

    long   bitp = 0;
    long   pointer_of_group_size = 0;
    long   pointer_of_group_width = 0;
    long   refsp = 0;
    long   nap = 0;
    long offsetdata = 0;

    double max;
    double min;
    int extraValues=0;

    size_t nv =0;

    if (*len ==0) return GRIB_NO_VALUES;

    if((err = grib_get_long_internal(gh,self->offsetsection,&offsetsection)) != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->offsetdata,&offsetdata)) != GRIB_SUCCESS)
        return err;
    if((err = grib_get_long_internal(gh,self->bits_per_value,&bits_per_value)) != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->decimal_scale_factor, &decimal_scale_factor))  != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->matrix_values, &matrix_values)) != GRIB_SUCCESS)return err;
    if((err = grib_get_long_internal(gh,self->snd_bitmap, &snd_bitmap)) != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->snd_ordr_wdiff, &snd_ordr_wdiff)) != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->general_ext, &general_ext)) != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->boustrophedonic, &boustrophedonic)) != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->width_spd_sp_desc, &width_spd_sp_desc)) != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->nap, &nap)) != GRIB_SUCCESS) return err;

    if ((abitmap=grib_find_accessor(gh,self->bitmap))!=NULL) {
        bitmap_len=grib_byte_count(abitmap);
        bitmap=(unsigned char*)grib_context_malloc_clear(a->context,sizeof(char)*bitmap_len);
        err=grib_unpack_bytes(abitmap,bitmap,&bitmap_len);
        if (err) {grib_context_free(a->context,bitmap); return err;}
    }

    two_ordr_spd = 1;
    plus1_spd = 0;

    if(bits_per_value == 0)
        return GRIB_NOT_IMPLEMENTED;

    n_sp_diff = two_ordr_spd*2+plus1_spd;
    /*     calculation of integer array   */

    sec_val  = (unsigned long*)grib_context_malloc(a->context,(n_vals)*sizeof(long));
    d = grib_power(decimal_scale_factor,10) ;
    max = val[0];
    min = max;
    for(i=0;i< n_vals;i++)
    {
        if      ( val[i] > max ) max = val[i];
        else if ( val[i] < min ) min = val[i];
    }
    min *= d;
    max *= d;

    /*bit_per_val_rectified_for_gribex = bits_per_value+8-bits_per_value%8;*/
    if (grib_get_nearest_smaller_value(gh,self->reference_value,min,&reference_value)
            !=GRIB_SUCCESS) {
        grib_context_log(a->context,GRIB_LOG_ERROR,
                "unable to find nearest_smaller_value of %g for %s",min,self->reference_value);
        return GRIB_INTERNAL_ERROR;
    }

    /*  the scale factor in Grib 1 is adjusted in gribex, for "normalization purpose" ... ?*/
    binary_scale_factor    = grib_get_binary_scale_fact(max,reference_value,bits_per_value,&err);

    divisor         = grib_power(-binary_scale_factor,2);


    for(i=0;i< n_vals;i++)
        sec_val[i] = (unsigned long)((((val[i]*d)-reference_value)*divisor)+0.5);

    /*  reverse the rows*/
    if(boustrophedonic)
        reverse_rows(sec_val,n_vals,nap,bitmap,bitmap_len);


    if(snd_ordr_wdiff)
        if((err =  spatial_difference(a->context,sec_val, n_vals, n_sp_diff, &bias))){
            grib_context_free(a->context,sec_val);
            return err;
        }



    /*   for(i=0;i < 10;i++)
      printf("packing value [%d] %g %ld     %ld bias %ld <<\n", i, val[i],sec_val[i],binary_scale_factor,bias );
     */
    nv        = n_vals-n_sp_diff;
    group_val = sec_val+n_sp_diff;

#if KEEP_OLD == 1

#else
    sd = grib_get_second_order_groups(a->context, group_val, nv);
#endif

    bitp   = 0;
    p1     = sd->size_of_group_array;

    bitp                         =   (width_spd_sp_desc*(n_sp_diff+1)) ;
    octet_start_group            =   (bitp+7)/8;

    bitp                         =   (p1*sd->nbits_per_widths);
    octet_start_group           +=   (bitp+7)/8;

    bitp                         =   (octet_start_group*8) + (sd->nbits_per_group_size*p1);
    n1                           =   (bitp+7)/8;

    bitp                         =   n1*8 + bits_per_value*p1;
    n2                           =   (bitp+7)/8;

    used_bits = n2*8;

    buff_len     = (n2+sd->packed_byte_count);

    if((a->offset+buff_len)%2) buff_len++;

    buf = NULL;
    buf = (unsigned char*)grib_context_malloc_clear(a->context,buff_len);

    buf_width_of_group    =  buf;
    buf_size_of_groups    =  buf+octet_start_group;
    buf_refs    =  buf+n1;
    buf_vals    =  buf+n2;

    pointer_of_group_size    = 0;
    pointer_of_group_width   = 0;
    refsp  = 0;
    bitp   = 0;

    for(i=0;i < n_sp_diff;i++)
        grib_encode_unsigned_longb(buf_width_of_group,sec_val[i],  &pointer_of_group_width,  width_spd_sp_desc);

    grib_encode_signed_longb(buf_width_of_group, bias, &pointer_of_group_width,  width_spd_sp_desc);

    if(pointer_of_group_width%8)
        pointer_of_group_width = 8+(pointer_of_group_width-(pointer_of_group_width%8));

    vcount    = n_sp_diff;

    for(i = 0;i<p1;i++){
        grib_encode_unsigned_longb(buf_width_of_group,sd->array_of_group_width[i],&pointer_of_group_width,sd->nbits_per_widths);
        grib_encode_unsigned_longb(buf_size_of_groups,sd->array_of_group_size[i], &pointer_of_group_size ,sd->nbits_per_group_size);
        grib_encode_unsigned_longb(buf_refs,  sd->array_of_group_refs[i],  &refsp  , bits_per_value);
        used_bits += sd->array_of_group_size[i]*sd->array_of_group_width[i];
        for(j=0; j < sd->array_of_group_size[i];j++){
            grib_encode_unsigned_longb(buf_vals, sec_val[vcount+j]-sd->array_of_group_refs[i] ,&bitp , sd->array_of_group_width[i]);

            /*    if(vcount+j < 10)
             printf(">>packing value [%ld] %g %ld     %ld nb %ld <<\n", vcount+j, val[vcount+j],sec_val[vcount+j],binary_scale_factor,sd->array_of_group_refs[i] );*/
        }
        vcount+= sd->array_of_group_size[i];
    }
    n_unused_bits = (buff_len*8)-used_bits;

    grib_buffer_replace(a, buf,buff_len,1,1);

    if((buff_len + (offsetdata-offsetsection)) %2) {
        buff_len ++;
        grib_update_size(a,buff_len);
    }

    octet_start_group += 1+ a->offset-offsetsection;
    if((err = grib_set_long_internal(gh,self->octet_start_group, octet_start_group)) != GRIB_SUCCESS) return err;

    n1 += 1+a->offset-offsetsection;
    if((err = grib_set_long_internal(gh,self->n1,n1)) != GRIB_SUCCESS) return err;

    n2 += 1+a->offset-offsetsection;
    if((err = grib_set_long_internal(gh,self->n2,n2)) != GRIB_SUCCESS) return err;

    extraValues=0;
    while (p1 > 65535) {
        p1-=65536;
        extraValues++;
    }

    if((err = grib_set_long_internal(gh,self->p1,p1)) != GRIB_SUCCESS) return err;

    if((err = grib_set_long_internal(gh,self->extraValues,extraValues)) != GRIB_SUCCESS) return err;

    if((err = grib_set_long_internal(gh,self->p2,n_vals - n_sp_diff)) != GRIB_SUCCESS) return err;

    if((err = grib_set_double_internal(gh,self->reference_value,    reference_value)) != GRIB_SUCCESS)return err;

    {
        /* Make sure we can decode it again */
        double ref = 1e-100;
        grib_get_double_internal(gh,self->reference_value,&ref);
        Assert(ref == reference_value);
    }

    if((err = grib_set_long_internal(gh,self->binary_scale_factor,         binary_scale_factor)) != GRIB_SUCCESS)  return err;

    if((err = grib_set_long_internal(gh,self->decimal_scale_factor, decimal_scale_factor))  != GRIB_SUCCESS)  return err;
    if((err = grib_set_long_internal(gh,self->width_widths,  sd->nbits_per_widths)) != GRIB_SUCCESS) return err;
    if((err = grib_set_long_internal(gh,self->width_lengths, sd->nbits_per_group_size)) != GRIB_SUCCESS) return err;


    err = grib_set_long_internal(gh,self->half_byte, n_unused_bits);
    if(err != GRIB_SUCCESS) return err;

#if KEEP_OLD == 1

#else

    grib_free_second_order_groups(a->context,sd);
#endif
    ;

    grib_context_free(a->context,buf);
    grib_context_free(a->context,sec_val);
    if (bitmap!=NULL) grib_context_free(a->context,bitmap);

    return GRIB_SUCCESS;
}
static int  unpack_double(grib_accessor* a, double* val, size_t *len)
{
    grib_accessor_data_2order_packing* self =  (grib_accessor_data_2order_packing*)a;

    size_t i = 0;
    size_t j = 0;
    size_t n_vals = 0;
    int err=0;

    long     vcount = 0, bias = 0;
    double   reference_value;
    long     binary_scale_factor;
    long     bits_per_value, decimal_scale_factor;
    long     n1 = 0, n2 = 0, extraValues = 0, p1 = 0, p2 = 0;

    long     offsetsection = 0, snd_bitmap = 0, snd_ordr_wdiff = 0;

    long  matrix_values    =0;
    long  general_ext    =0;
    long  boustrophedonic =0;
    long  two_ordr_spd =0;
    long  plus1_spd  =0;

    long  nbits_per_width =0;
    long  nbits_per_group_size =0;
    long  octet_start_group =0;
    long  width_spd_sp_desc =0;
    grib_handle* gh = grib_handle_of_accessor(a);

    unsigned char* buf_size_of_groups = (unsigned char*)gh->buffer->data;
    unsigned char* buf_width_of_group = (unsigned char*)gh->buffer->data;
    unsigned char* bufrefs = (unsigned char*)gh->buffer->data;
    unsigned char* bufvals = (unsigned char*)gh->buffer->data;

    double s = 0;
    double d = 0;

    double max = 0;
    double min = 0;

    unsigned long*  sec_val    = NULL;
    long  ref_vals    = 0;
    short  n_sp_diff = 0;

    short f_size_of_group = 0;
    short f_width_of_group = 0;

    long bitp = 0;
    long pointer_of_group_size = 0;
    long pointer_of_group_width = 0;
    long refsp = 0;
    long nap = 0;
    long nn=0;
    unsigned char* bitmap=NULL;
    grib_accessor* abitmap=NULL;
    size_t bitmap_len=0;

    err=grib_value_count(a,&nn);
    n_vals=nn;

    if((err = grib_get_long_internal(gh,self->offsetsection,&offsetsection))
            != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->bits_per_value,&bits_per_value))
            != GRIB_SUCCESS) return err;
    if((err = grib_get_double_internal(gh,self->reference_value, &reference_value))
            != GRIB_SUCCESS)return err;
    if((err = grib_get_long_internal(gh,self->binary_scale_factor, &binary_scale_factor))
            != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->decimal_scale_factor, &decimal_scale_factor))
            != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->n1,&n1))  != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->n2, &n2)) != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->p1, &p1)) != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->extraValues, &extraValues)) != GRIB_SUCCESS) return err;

    p1=p1+65536*extraValues;

    if((err = grib_get_long_internal(gh,self->p2, &p2)) != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->matrix_values, &matrix_values))
            != GRIB_SUCCESS)return err;
    if((err = grib_get_long_internal(gh,self->snd_bitmap, &snd_bitmap))
            != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->snd_ordr_wdiff, &snd_ordr_wdiff))
            != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->general_ext, &general_ext))
            != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->boustrophedonic, &boustrophedonic))
            != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->two_ordr_spd, &two_ordr_spd))
            != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->plus1_spd, &plus1_spd))
            != GRIB_SUCCESS)  return err;
    if((err = grib_get_long_internal(gh,self->width_widths, &nbits_per_width))
            != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->width_lengths, &nbits_per_group_size))
            != GRIB_SUCCESS) return err;
    if((err = grib_get_long_internal(gh,self->octet_start_group, &octet_start_group))
            != GRIB_SUCCESS) return err;

    if((err = grib_get_long_internal(gh,self->width_spd_sp_desc, &width_spd_sp_desc))
            != GRIB_SUCCESS) width_spd_sp_desc=-1;

    if((err = grib_get_long_internal(gh,self->nap, &nap)) != GRIB_SUCCESS) return err;

    self->dirty=0;

    n_sp_diff = two_ordr_spd*2+plus1_spd;

    Assert(bits_per_value < (sizeof(unsigned long)*8)-1);

    if ((abitmap=grib_find_accessor(gh,self->bitmap))!=NULL) {
        bitmap_len=grib_byte_count(abitmap);
        bitmap=(unsigned char*)grib_context_malloc_clear(a->context,sizeof(char)*bitmap_len);
        err=grib_unpack_bytes(abitmap,bitmap,&bitmap_len);
        if (err) {grib_context_free(a->context,bitmap); return err;}
    }

    if(bits_per_value == 0)
        return GRIB_NOT_IMPLEMENTED;

    /* I have everything now start decoding       */
    /*
    fprintf(stdout,"\n****************************************\n");
    fprintf(stdout," bits_per_value = %ld\n", bits_per_value);
    fprintf(stdout," reference_value = %g\n", reference_value);
    fprintf(stdout," binary_scale_factor = %ld\n", binary_scale_factor);
    fprintf(stdout," decimal_scale_factor = %ld\n", decimal_scale_factor);
    fprintf(stdout," n1 = %ld\n", n1);
    fprintf(stdout," n2 = %ld\n", n2);
    fprintf(stdout," p1 = %ld\n", p1);
    fprintf(stdout," p2 = %ld\n", p2);
    fprintf(stdout," matrix_values = %ld\n", matrix_values);
    fprintf(stdout," snd_bitmap = %ld\n", snd_bitmap);
    fprintf(stdout," snd_ordr_wdiff = %ld\n", snd_ordr_wdiff);
    fprintf(stdout," general_ext = %ld\n", general_ext);
    fprintf(stdout," boustrophedonic = %ld\n", boustrophedonic);
    fprintf(stdout," two_ordr_spd = %ld \n", two_ordr_spd);

    fprintf(stdout," plus1_spd = %ld\n", plus1_spd);

    fprintf(stdout," n_sp_diff = %d\n", n_sp_diff);
    fprintf(stdout," width_widths = %ld\n", nbits_per_group_size);
    fprintf(stdout," width_lengths = %ld\n", nbits_per_width);
    fprintf(stdout," octet_start_group = %ld\n", octet_start_group);
    fprintf(stdout," width_spd_sp_desc = %ld\n", width_spd_sp_desc);

    fprintf(stdout," offsetsection = %ld\n", offsetsection);
    fprintf(stdout," offset w = %ld\n", octet_start_group + offsetsection);
    fprintf(stdout,"\n****************************************\n");
    */
    if(snd_bitmap || matrix_values)
        return GRIB_NOT_IMPLEMENTED;

    sec_val  = (unsigned long*)grib_context_malloc(a->context,(n_vals)*sizeof(unsigned long));

    buf_width_of_group  +=  a->offset;
    buf_size_of_groups +=  offsetsection+(octet_start_group-1); /* -1 because of documented starting at 1(and not 0)*/
    bufrefs +=  offsetsection+n1-1;                  /* -1 because of documented starting at 1(and not 0)*/

    pointer_of_group_size  = 0;
    pointer_of_group_width    = 0;
    refsp   = 0;

    for(i=0;i < n_sp_diff;i++)
        sec_val[i] =  grib_decode_unsigned_long(buf_width_of_group,  &pointer_of_group_width,  width_spd_sp_desc);


    bias   =  grib_decode_signed_longb(buf_width_of_group,  &pointer_of_group_width,  width_spd_sp_desc);

    bufvals += offsetsection+n2-1;
    bitp   =  0;
    vcount =  n_sp_diff;

    if(pointer_of_group_width%8)
        pointer_of_group_width = 8+(pointer_of_group_width-(pointer_of_group_width%8));
#if KEEP_OLD == 1
    if(sd == NULL){
        sd = grib_context_malloc_clear(a->context,sizeof(second_order_packed));
        sd->packed_byte_count      = 0;
        sd->nbits_per_group_size   = nbits_per_group_size;
        sd->nbits_per_widths       = nbits_per_width;
        sd->size_of_group_array    = p1;
        sd->array_of_group_size    = grib_context_malloc_clear(a->context,sizeof(unsigned long)*sd->size_of_group_array);
        sd->array_of_group_width   = grib_context_malloc_clear(a->context,sizeof(unsigned long)*sd->size_of_group_array);
        sd->array_of_group_refs    = grib_context_malloc_clear(a->context,sizeof( long)*sd->size_of_group_array);
    }
#endif
    for(i=0;i < p1;i++){
        f_width_of_group    = (short) grib_decode_unsigned_long(buf_width_of_group,  &pointer_of_group_width,     nbits_per_width);
        f_size_of_group     = (short) grib_decode_unsigned_long(buf_size_of_groups,  &pointer_of_group_size, nbits_per_group_size);
        ref_vals            =         grib_decode_unsigned_long(bufrefs,  &refsp,    bits_per_value);
#if KEEP_OLD == 1

        if(sd->packed_byte_count == 0){
            sd->array_of_group_width[i]  = f_width_of_group;
            sd->array_of_group_size[i]   = f_size_of_group;
            sd->array_of_group_refs[i]   = ref_vals;
        }
#endif
        for(j=0; j < f_size_of_group;j++){
            sec_val[vcount+j] = ref_vals + grib_decode_unsigned_long(bufvals,  &bitp, f_width_of_group);
        }
        vcount += f_size_of_group;
    }
#if KEEP_OLD == 1
    if(sd->packed_byte_count == 0) sd->packed_byte_count = (bitp+7)/8;
#endif

    Assert (n_vals == vcount);
    /*for(i=0;i < 10;i++)
    printf("readvalue [%d] %ld     %ld bias %ld <<\n", i,sec_val[i],binary_scale_factor,bias );*/

    if(snd_ordr_wdiff)
        de_spatial_difference(a->context,sec_val, n_vals, n_sp_diff, bias);

    if(boustrophedonic)
        reverse_rows(sec_val,n_vals,nap,bitmap,bitmap_len);

    s = grib_power(binary_scale_factor,2);
    d = grib_power(-decimal_scale_factor,10) ;

    for(i=0;i < n_vals;i++)
        val[i] = (double) ((((double)sec_val[i])*s)+reference_value)*d;

    max = val[0];
    min = max;
    for(i=0;i< n_vals;i++)
    {
        if ( val[i] > max )
            max = val[i];
        else if ( val[i] < min )
            min = val[i];
    }
    min *= d;
    max *= d;

    grib_context_free(a->context,sec_val);
    if (bitmap!=NULL) grib_context_free(a->context,bitmap);

    return err;
}