static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
    grib_accessor_data_apply_bitmap* self =  (grib_accessor_data_apply_bitmap*)a;
    int err = 0;
    size_t bmaplen = *len;
    long coded_n_vals = 0;
    double* coded_vals = NULL;
    long i = 0;
    long j = 0;
    double missing_value = 0;

    if (*len ==0) return GRIB_NO_VALUES;

    if(!grib_find_accessor(a->parent->h,self->bitmap)){
        err = grib_set_double_array_internal(a->parent->h,self->coded_values,val,*len);
        /*printf("SETTING TOTAL number_of_data_points %s %ld\n",self->number_of_data_points,*len);*/
        if(self->number_of_data_points)
            grib_set_long_internal(a->parent->h,self->number_of_data_points,*len);
        return err;
    }

    if((err = grib_get_double_internal(a->parent->h,self->missing_value,&missing_value)) != GRIB_SUCCESS)
        return err;

    if((err = grib_set_double_array_internal(a->parent->h,self->bitmap,val,bmaplen)) != GRIB_SUCCESS)
        return err;

    coded_n_vals = *len;

    if(coded_n_vals <  1){
        err = grib_set_double_array_internal(a->parent->h,self->coded_values,NULL,0);
        return err;
    }

    coded_vals = (double*)grib_context_malloc_clear(a->parent->h->context,coded_n_vals*sizeof(double));
    if(!coded_vals) return GRIB_OUT_OF_MEMORY;

    for(i=0; i<*len ; i++)
    {
        if(val[i] != missing_value) {
            coded_vals[j++] = val[i];
        }
    }

    err = grib_set_double_array_internal(a->parent->h,self->coded_values,coded_vals,j);
    if (j==0) {
        if (self->number_of_values)
            err=grib_set_long_internal(a->parent->h,self->number_of_values,0);
        if (self->binary_scale_factor)
            err=grib_set_long_internal(a->parent->h,self->binary_scale_factor,0);
    }

    grib_context_free(a->parent->h->context,coded_vals);

    return err;
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
  int ret=GRIB_SUCCESS;
  long bitmap_present=0;

  grib_accessor_data_apply_gdsnotpresent* self =  (grib_accessor_data_apply_gdsnotpresent*)a;

  if (*len ==0) return GRIB_NO_VALUES;

  ret=grib_set_long(a->parent->h,self->bitmap_present,bitmap_present);
  if(ret) {
    grib_context_log(a->parent->h->context, GRIB_LOG_ERROR,
       "Accessor %s cannont pack value for %s error %d \n", a->name, self->bitmap_present, ret);
    return ret;
  }

#if 0
  if(!grib_find_accessor(a->parent->h,self->bitmap)){
    grib_context_log(a->parent->h->context, GRIB_LOG_ERROR,
       "Accessor %s cannont access bitmap \n", a->name, self->bitmap_present, ret);
    return ret;
  }
#endif


  ret = grib_set_double_array_internal(a->parent->h,self->coded_values,val,*len);
  if(ret) {
    grib_context_log(a->parent->h->context, GRIB_LOG_ERROR,
       "Accessor %s cannont pack value for %s error %d \n", a->name, self->coded_values, ret);
    return ret;
  }

  return ret;
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
  grib_accessor_data_g2shsimple_packing* self =  (grib_accessor_data_g2shsimple_packing*)a;
  int err =  GRIB_SUCCESS;

  size_t coded_n_vals = *len-1;
  size_t n_vals = *len;

  if (*len ==0) return GRIB_NO_VALUES;

  self->dirty=1;

  if((err = grib_set_double_internal(grib_handle_of_accessor(a),self->real_part,*val)) != GRIB_SUCCESS)
    return err;
  {
    /* Make sure we can decode it again */
    double ref = 1e-100;
    grib_get_double_internal(grib_handle_of_accessor(a),self->real_part,&ref);
    Assert(ref == *val);
  }

  val++;

  if((err = grib_set_double_array_internal(grib_handle_of_accessor(a),self->coded_values,val,coded_n_vals)) != GRIB_SUCCESS)
    return err;

  *len =  n_vals;

    if((err = grib_set_long_internal(grib_handle_of_accessor(a),self->numberOfValues,(long)n_vals)) != GRIB_SUCCESS)
    return err;

  return err;
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
  grib_accessor_g2latlon* self = (grib_accessor_g2latlon*)a;
  int ret = 0;

  double grid[6];
  size_t size = 6;

  if(*len < 1){
    ret = GRIB_ARRAY_TOO_SMALL;
    return ret;
  }

  if(self->given)
  {
    long given        = *val != GRIB_MISSING_DOUBLE;
    if((ret = grib_set_long_internal(a->parent->h, self->given,given)) != GRIB_SUCCESS)
      return ret;
  }


  if((ret = grib_get_double_array_internal(a->parent->h, self->grid,grid,&size)) != GRIB_SUCCESS)
    return ret;

  if ( (self->index == 1 || self->index == 3) && *val < 0 ) grid[self->index] = 360+*val;
  else grid[self->index] = *val;

  return grib_set_double_array_internal(a->parent->h, self->grid,grid,size);
}
static int  unpack_double(grib_accessor* a, double* val, size_t *len)
{
    grib_accessor_data_dummy_field* self =  (grib_accessor_data_dummy_field*)a;
    size_t i = 0;
    size_t n_vals = 0;
    long numberOfPoints;
    double missing_value = 0;
    int err = 0;

    if((err = grib_get_long_internal(a->parent->h,self->numberOfPoints, &numberOfPoints))
            != GRIB_SUCCESS)  return err;
    n_vals =numberOfPoints;

    if((err = grib_get_double_internal(a->parent->h,self->missing_value, &missing_value))
            != GRIB_SUCCESS)		return err;

    if(*len < n_vals) {
        *len = n_vals;
        return GRIB_ARRAY_TOO_SMALL;
    }

    for(i=0; i < n_vals; i++)
        val[i] = missing_value;

    if(grib_find_accessor(a->parent->h,self->bitmap)) {
        if((err = grib_set_double_array_internal(a->parent->h,self->bitmap,val,n_vals)) != GRIB_SUCCESS)
            return err;
    }

    *len = (long) n_vals;
    return err;
}
static int pack_long(grib_accessor* a, const long* val, size_t *len)
{
  double* values=NULL;
  size_t size=0;
  int ret=0;
  grib_accessor_bits_per_value* self= (grib_accessor_bits_per_value*)a;
  grib_context* c=a->context;
  grib_handle* h=grib_handle_of_accessor(a);

  if ( (ret=grib_get_size(h,self->values,&size)) != GRIB_SUCCESS) return ret;

  values=(double*)grib_context_malloc(c,size*sizeof(double));
  if (!values) return GRIB_OUT_OF_MEMORY;

  if((ret = grib_get_double_array_internal(h,self->values,values,&size))
       != GRIB_SUCCESS) {
        grib_context_free(c,values);
        return ret;
  }

  if((ret = grib_set_long_internal(h, self->bits_per_value,*val))
      != GRIB_SUCCESS) return ret;

  if((ret = grib_set_double_array_internal(h, self->values,values,size))
      != GRIB_SUCCESS) return ret;

  grib_context_free(c,values);

  return GRIB_SUCCESS;
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
  grib_accessor_data_shsimple_packing* self =  (grib_accessor_data_shsimple_packing*)a;
  int err =  GRIB_SUCCESS;

  size_t coded_n_vals = *len-1;
  size_t n_vals = *len;

  self->dirty=1;

  if (*len ==0) return GRIB_NO_VALUES;

  if((err = grib_set_double_internal(a->parent->h,self->real_part,*val)) != GRIB_SUCCESS)
    return err;


  val++;

  if((err = grib_set_double_array_internal(a->parent->h,self->coded_values,val,coded_n_vals)) != GRIB_SUCCESS)
  return err;


  *len =  n_vals;

  return err;

}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
    double* values=NULL;
    size_t size=0;
    double missingValue=0;
    long missingValuesPresent = 0;
    int ret=0,i=0;
    grib_accessor_offset_values* self= (grib_accessor_offset_values*)a;
    grib_context* c=a->context;
    grib_handle* h=grib_handle_of_accessor(a);

    if (*val==0) return GRIB_SUCCESS;

    if((ret = grib_get_double_internal(h,self->missingValue,&missingValue)) != GRIB_SUCCESS) {
        return ret;
    }
    if((ret=grib_get_long_internal(h,"missingValuesPresent",&missingValuesPresent)) != GRIB_SUCCESS) {
        return ret;
    }

    if ( (ret=grib_get_size(h,self->values,&size)) != GRIB_SUCCESS) return ret;

    values=(double*)grib_context_malloc(c,size*sizeof(double));
    if (!values) return GRIB_OUT_OF_MEMORY;

    if((ret = grib_get_double_array_internal(h,self->values,values,&size)) != GRIB_SUCCESS) {
        grib_context_free(c,values);
        return ret;
    }

    for (i=0;i<size;i++) {
        if (missingValuesPresent) {
            if (values[i]!=missingValue) values[i]+=*val;
        } else {
            values[i]+=*val;
        }
    }

    if((ret = grib_set_double_array_internal(h, self->values,values,size)) != GRIB_SUCCESS) return ret;

    grib_context_free(c,values);

    return GRIB_SUCCESS;
}
static int    pack_long   (grib_accessor* a, const long* val, size_t *len)
{
  long missing=255;
  int ret=0;
  size_t size=0;
  double* values;
  grib_context* c=a->parent->h->context;
  grib_handle* h=a->parent->h;
  grib_accessor_gds_is_present* self = (grib_accessor_gds_is_present*)a;

  if (*val != 1) return GRIB_NOT_IMPLEMENTED;

  if ( (ret=grib_get_size(h,self->values,&size)) != GRIB_SUCCESS) return ret;

  values=(double*)grib_context_malloc(c,size*sizeof(double));
  if (!values) return GRIB_OUT_OF_MEMORY;

  if((ret = grib_get_double_array_internal(h,self->values,values,&size))
       != GRIB_SUCCESS) {
        grib_context_free(c,values);
        return ret;
  }

  if((ret = grib_set_long_internal(h, self->gds_present,*val))
      != GRIB_SUCCESS) return ret;

  if((ret = grib_set_long_internal(h, self->bitmap_present,*val))
      != GRIB_SUCCESS) return ret;



  if((ret = grib_set_long_internal(h, self->grid_definition,missing))
      != GRIB_SUCCESS) return ret;

  if((ret = grib_set_double_array_internal(h, self->values,values,size))
      != GRIB_SUCCESS) return ret;

  grib_context_free(c,values);

  return GRIB_SUCCESS;
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
  double* values=NULL;
  double missingValue=0;
  size_t size=0;
  int ret=0,i=0;
  grib_accessor_scale_values* self= (grib_accessor_scale_values*)a;
  grib_context* c=a->parent->h->context;
  grib_handle* h=a->parent->h;

  if (*val==1) return GRIB_SUCCESS;

  if((ret = grib_get_double_internal(h,self->missingValue,&missingValue))
       != GRIB_SUCCESS) {
        return ret;
  }

  if ( (ret=grib_get_size(h,self->values,&size)) != GRIB_SUCCESS) return ret;

  values=(double*)grib_context_malloc(c,size*sizeof(double));
  if (!values) return GRIB_OUT_OF_MEMORY;

  if((ret = grib_get_double_array_internal(h,self->values,values,&size))
       != GRIB_SUCCESS) {
        grib_context_free(c,values);
        return ret;
  }

  for (i=0;i<size;i++)
    if (values[i]!=missingValue) values[i]*=*val;

  if((ret = grib_set_double_array_internal(h, self->values,values,size))
      != GRIB_SUCCESS) return ret;

  grib_context_free(c,values);

  return GRIB_SUCCESS;
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
    grib_accessor_data_apply_boustrophedonic_bitmap* self =  (grib_accessor_data_apply_boustrophedonic_bitmap*)a;
    int err = 0;
    size_t bmaplen = *len;
    size_t irow = 0;
    long coded_n_vals = 0;
    double* coded_vals = NULL;
    double *values=0;
    long i = 0;
    long j = 0;
    long numberOfPoints, numberOfRows, numberOfColumns;
    double missing_value = 0;

    if (*len ==0) return GRIB_NO_VALUES;

    if(!grib_find_accessor(a->parent->h,self->bitmap)){
        err = grib_set_double_array_internal(a->parent->h,self->coded_values,val,*len);
        /*printf("SETTING TOTAL number_of_data_points %s %ld\n",self->number_of_data_points,*len);*/
        /*if(self->number_of_data_points)
            grib_set_long_internal(a->parent->h,self->number_of_data_points,*len);*/
        return err;
    }

    if((err = grib_get_double_internal(a->parent->h,self->missing_value,&missing_value)) != GRIB_SUCCESS)
        return err;

    err=grib_get_long_internal(a->parent->h,self->numberOfRows, &numberOfRows);
    if (err) return err;
    err=grib_get_long_internal(a->parent->h,self->numberOfColumns, &numberOfColumns);
    if (err) return err;
    err=grib_get_long_internal(a->parent->h,self->numberOfPoints,&numberOfPoints);
    if (err) return err;
    Assert(numberOfPoints == bmaplen);

    /* Create a copy of the incoming 'val' array because we're going to change it */
    values = (double*)grib_context_malloc_clear(a->parent->h->context, sizeof(double)*numberOfPoints);
    if (!values) return GRIB_OUT_OF_MEMORY;
    for(i=0; i<numberOfPoints; ++i) {
        values[i] = val[i];
    }

    /* Boustrophedonic ordering must be applied to the bitmap (See GRIB-472) */
    for(irow=0; irow<numberOfRows; ++irow)
    {
        if (irow%2)
        {
            size_t k = 0;
            size_t start = irow*numberOfColumns;
            size_t end = start + numberOfColumns - 1;
            size_t mid = (numberOfColumns - 1)/2;
            for(k=0; k<mid; ++k)
            {
                double temp = values[start+k];
                values[start+k] = values[end-k];
                values[end-k] = temp;
            }
        }
    }
    /* Now set the bitmap based on the array with the boustrophedonic ordering */
    if((err = grib_set_double_array_internal(a->parent->h,self->bitmap,values,bmaplen)) != GRIB_SUCCESS)
        return err;

    grib_context_free(a->parent->h->context,values);

    coded_n_vals = *len;

    if(coded_n_vals < 1){
        err = grib_set_double_array_internal(a->parent->h,self->coded_values,NULL,0);
        return err;
    }

    coded_vals = (double*)grib_context_malloc_clear(a->parent->h->context,coded_n_vals*sizeof(double));
    if(!coded_vals) return GRIB_OUT_OF_MEMORY;

    for(i=0; i<*len ; i++)
    {
        /* To set the coded values, look at 'val' (the original array) */
        /* NOT 'values' (bitmap) which we swapped about */
        if(val[i] != missing_value) {
            coded_vals[j++] = val[i];
        }
    }

    err = grib_set_double_array_internal(a->parent->h,self->coded_values,coded_vals,j);
    if (j==0) {
        /*if (self->number_of_values)
            err=grib_set_long_internal(a->parent->h,self->number_of_values,0);*/
        if (self->binary_scale_factor)
            err=grib_set_long_internal(a->parent->h,self->binary_scale_factor,0);
    }

    grib_context_free(a->parent->h->context,coded_vals);

    return err;
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
    grib_accessor_data_apply_boustrophedonic* self =  (grib_accessor_data_apply_boustrophedonic*)a;
    size_t plSize=0;
    long *pl=0;
    double *values=0;
    double *pvalues=0;
    double *pval=0;
    size_t valuesSize=0;
    long i,j;
    int ret;
    long numberOfPoints,numberOfRows,numberOfColumns;

    ret=grib_get_long_internal(grib_handle_of_accessor(a),self->numberOfPoints,&numberOfPoints);
    if (ret) return ret;

    if(*len < numberOfPoints) {
        *len = numberOfPoints;
        return GRIB_ARRAY_TOO_SMALL;
    }

    valuesSize=numberOfPoints;

    values=(double*)grib_context_malloc_clear(a->context,sizeof(double)*numberOfPoints);

    pvalues=values;
    pval=(double*)val;

    ret=grib_get_long_internal(grib_handle_of_accessor(a),self->numberOfRows,&numberOfRows);
    if (ret) return ret;

    ret=grib_get_long_internal(grib_handle_of_accessor(a),self->numberOfColumns,&numberOfColumns);
    if (ret) return ret;

    if (grib_get_size(grib_handle_of_accessor(a),self->pl,&plSize) == GRIB_SUCCESS) {
        Assert(plSize==numberOfRows);
        pl=(long*)grib_context_malloc_clear(a->context,sizeof(long)*plSize);
        ret=grib_get_long_array_internal(grib_handle_of_accessor(a),self->pl,pl,&plSize);
        if (ret) return ret;

        for (j=0;j<numberOfRows;j++) {
            if (j%2) {
                pvalues+=pl[j];
                for (i=0;i<pl[j] ;i++) { *(--pvalues)=*(pval++); }
                pvalues+=pl[j];
            } else {
                for (i=0;i<pl[j];i++) *(pvalues++)=*(pval++);
            }
        }

        grib_context_free(a->context,pl);

    } else {

        for (j=0;j<numberOfRows;j++) {
            if (j%2) {
                pvalues+=numberOfColumns;
                for (i=0;i<numberOfColumns;i++) *(--pvalues)=*(pval++);
                pvalues+=numberOfColumns;
            } else {
                for (i=0;i<numberOfColumns;i++) *(pvalues++)=*(pval++);
            }
        }

    }
    ret=grib_set_double_array_internal(grib_handle_of_accessor(a),self->values,values,valuesSize);
    if (ret) return ret;

    grib_context_free(a->context,values);

    return ret;
}
static int pack_long(grib_accessor* a, const long* val, size_t *len)
{
  long bitsPerValue=0;
  double* values=NULL;
  size_t size=0;
  int ret=0;
  grib_accessor_decimal_precision* self= (grib_accessor_decimal_precision*)a;
  grib_context* c=a->parent->h->context;
  grib_handle* h=a->parent->h;

  if (!self->values) {
    if((ret = grib_set_long_internal(h, self->bits_per_value,0))
        != GRIB_SUCCESS) return ret;
        
    if((ret = grib_set_long_internal(h, self->decimal_scale_factor,*val))
        != GRIB_SUCCESS) return ret;

    if((ret = grib_set_long_internal(h, self->changing_precision,1))
        != GRIB_SUCCESS) {
      grib_context_free(c,values);
      return ret;
        }

    return GRIB_SUCCESS;
  }

  if ( (ret=grib_get_size(h,self->values,&size)) != GRIB_SUCCESS) return ret;

  values=(double*)grib_context_malloc(c,size*sizeof(double));
  if (!values) return GRIB_OUT_OF_MEMORY;

  if((ret = grib_get_double_array_internal(h,self->values,values,&size))
       != GRIB_SUCCESS) {
        grib_context_buffer_free(c,values);
        return ret;
  }

  if((ret = grib_set_long_internal(h, self->decimal_scale_factor,*val))
      != GRIB_SUCCESS) { 
        grib_context_buffer_free(c,values);
	  return ret;
	  }

  if((ret = grib_set_long_internal(h, self->bits_per_value,bitsPerValue))
      != GRIB_SUCCESS) {
        grib_context_free(c,values);
	  return ret;
	 }

     if((ret = grib_set_long_internal(h, self->changing_precision,1))
         != GRIB_SUCCESS) {
       grib_context_free(c,values);
       return ret;
         }

  if((ret = grib_set_double_array_internal(h, self->values,values,size))
      != GRIB_SUCCESS) {
        grib_context_buffer_free(c,values);
	  return ret;
	 }

  grib_context_free(c,values);

  return GRIB_SUCCESS;
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
    grib_accessor_data_g2secondary_bitmap* self =  (grib_accessor_data_g2secondary_bitmap*)a;

    int err = 0;

    long primary_len = 0;
    long secondary_len = 0;
    double* primary_bitmap = NULL;
    double* secondary_bitmap = NULL;
    long i = 0;
    long j = 0;
    long on = 0;
    long k;
    long m;
    double missing_value = 0;
    double present_value = 0;
    long expand_by =0;

    if (*len ==0) return GRIB_NO_VALUES;

    if((err = grib_get_long(a->parent->h,self->expand_by,&expand_by)) != GRIB_SUCCESS)
        return err;

    if((err = grib_get_double_internal(a->parent->h,self->missing_value,&missing_value)) != GRIB_SUCCESS)
        return err;

    Assert(expand_by);

    if(*len % expand_by)
    {
        /*TODO: issue warning */
        return GRIB_ENCODING_ERROR;
    }

    primary_len = *len / expand_by;
    primary_bitmap= (double*)grib_context_malloc_clear(a->parent->h->context,primary_len*sizeof(double));
    if(!primary_bitmap) return GRIB_OUT_OF_MEMORY;

    secondary_len = *len ;
    secondary_bitmap= (double*)grib_context_malloc_clear(a->parent->h->context,secondary_len*sizeof(double));
    if(!secondary_bitmap) {
        grib_context_free(a->parent->h->context,primary_bitmap);
        return GRIB_OUT_OF_MEMORY;
    }

    if(missing_value == 0)
        present_value = 1;
    else
        present_value = 0;

    k = 0;
    m = 0;
    for(i=0; i<*len ; i += expand_by)
    {
        int cnt = 0;
        for(j = 0; j < expand_by; j++)
            if(val[i+j] == missing_value)
                cnt++;

        if(cnt == expand_by) /* all expand_by values are missing */
            primary_bitmap[k++] = missing_value;
        else {
            primary_bitmap[k++] = present_value;
            for(j = 0; j < expand_by; j++)
                secondary_bitmap[m++] = val[i+j];
            on++;
        }
    }

    *len = k;

    Assert(k == primary_len);

    err = grib_set_double_array_internal(a->parent->h,self->primary_bitmap,primary_bitmap,k);
    if(err == GRIB_SUCCESS)
        err = grib_set_double_array_internal(a->parent->h,self->secondary_bitmap,secondary_bitmap,m);

    grib_context_free(a->parent->h->context,primary_bitmap);
    grib_context_free(a->parent->h->context,secondary_bitmap);

    if(err == GRIB_SUCCESS)
        err = grib_set_long_internal(a->parent->h,self->number_of_values,*len * expand_by);

    return err;
}